diff --git a/include/field.h b/include/field.h index a109b14..4e8dfd7 100755 --- a/include/field.h +++ b/include/field.h @@ -19,12 +19,10 @@ private: size_t FieldSize = 4; std::vector field; - std::vector processLine(const std::vector &sourceLine, Score &score); - - Line getRow(size_t rowIndex) const; - std::vector getColumn(size_t columnIndex) const; - void setRow(size_t rowIndex, const std::vector &line); - void setColumn(size_t columnIndex, const std::vector &line); + Line& getRow(size_t rowIndex) const; + Line& getColumn(size_t columnIndex) const; + void setRow(size_t rowIndex, const Line &line); + void setColumn(size_t columnIndex, const Line &line); void reset(); void setSize(size_t size); diff --git a/include/line.h b/include/line.h index 98f18c8..f60ee74 100644 --- a/include/line.h +++ b/include/line.h @@ -10,4 +10,18 @@ struct Line { Line(size_t length); void process(); + + void push_back(Tile tile); + size_t size(); + size_t size() const; + + Tile& operator[](size_t index); + const Tile& operator[](size_t index) const; + bool operator==(const Line &other) const; + bool operator!=(const Line &other) const; + + std::vector::iterator begin(); + std::vector::iterator end(); + std::vector::const_iterator begin() const; + std::vector::const_iterator end() const; }; \ No newline at end of file diff --git a/main.cpp b/main.cpp index e378372..818aaea 100755 --- a/main.cpp +++ b/main.cpp @@ -16,19 +16,19 @@ int main() { { case 'w': field.moveUp(); - field.spawnTile(); + field.spawnTile(field.getEmptyTiles()); break; case 's': field.moveDown(); - field.spawnTile(); + field.spawnTile(field.getEmptyTiles()); break; case 'a': field.moveLeft(); - field.spawnTile(); + field.spawnTile(field.getEmptyTiles()); break; case 'd': field.moveRight(); - field.spawnTile(); + field.spawnTile(field.getEmptyTiles()); break; default: return 0; diff --git a/source/field.cpp b/source/field.cpp index ca84ef1..04e2d6c 100755 --- a/source/field.cpp +++ b/source/field.cpp @@ -20,60 +20,24 @@ Public methods: */ // PRIVATE -std::vector Field::processLine(const std::vector& sourceLine, Score &score) { - std::vector result; - Tile pending = 0; - bool hasPending = false; - - for (Tile element : sourceLine) { - if (element == 0) continue; - - if (!hasPending) { - pending = element; - hasPending = true; - continue; - } - - if (element == pending) { - result.push_back(pending * 2); - score += pending * 2; - hasPending = false; - pending = 0; - } else { - result.push_back(pending); - pending = element; - } - } - - if (hasPending) { - result.push_back(pending); - } - - while (result.size() < sourceLine.size()) { - result.push_back(0); - } - - return result; -} - -Line Field::getRow(size_t rowIndex) const { +Line& Field::getRow(size_t rowIndex) const { return this->field[rowIndex]; } -std::vector Field::getColumn(size_t columnIndex) const { +Line& Field::getColumn(size_t columnIndex) const { // from top to bottom - std::vector column; + 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 std::vector &line) { +void Field::setRow(size_t rowIndex, const Line &line) { this->field[rowIndex] = line; } -void Field::setColumn(size_t columnIndex, const std::vector &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]; @@ -81,7 +45,10 @@ void Field::setColumn(size_t columnIndex, const std::vector &line) { } void Field::reset() { - this->field.resize(this->FieldSize, std::vector(this->FieldSize, 0)); + this->field.resize(this->FieldSize); + for (size_t i = 0; i < this->FieldSize; ++i) { + this->field[i] = Line(this->FieldSize); + } } // PUBLIC @@ -89,7 +56,7 @@ Field::Field(size_t fieldSize) : mt(std::random_device{}()), FieldSize(fieldSize this->reset(); } -void printVector(const std::vector &arr) { +void printVector(const Line &arr) { for (size_t i = 0; i < arr.size(); ++i) { printf("%llu ", arr[i]); } @@ -99,9 +66,9 @@ void printVector(const std::vector &arr) { bool Field::moveUp() { auto oldField = this->field; for (size_t i = 0; i < this->FieldSize; ++i) { - std::vector column; + Line column; column = getColumn(i); - column = processLine(column, this->score); + column.process(); setColumn(i, column); } return this->field != oldField; @@ -110,10 +77,10 @@ bool Field::moveUp() { bool Field::moveDown() { auto oldField = this->field; for (size_t i = 0; i < this->FieldSize; ++i) { - std::vector column; + Line column; column = getColumn(i); std::reverse(column.begin(), column.end()); - column = processLine(column, this->score); + column.process(); std::reverse(column.begin(), column.end()); setColumn(i, column); } @@ -122,10 +89,10 @@ bool Field::moveDown() { bool Field::moveLeft() { auto oldField = this->field; - std::vector row; + Line row; for (size_t i = 0; i < this->FieldSize; ++i) { row = getRow(i); - row = processLine(row, this->score); + row.process(); setRow(i, row); } return this->field != oldField; @@ -133,11 +100,11 @@ bool Field::moveLeft() { bool Field::moveRight() { auto oldField = this->field; - std::vector row; + Line row; for (size_t i = 0; i < this->FieldSize; ++i) { row = getRow(i); std::reverse(row.begin(), row.end()); - row = processLine(row, this->score); + row.process(); std::reverse(row.begin(), row.end()); setRow(i, row); } diff --git a/source/line.cpp b/source/line.cpp index e713e9c..92755f6 100644 --- a/source/line.cpp +++ b/source/line.cpp @@ -1,5 +1,11 @@ #include "line.h" +/* +Fields: + std::vector line; + Score score; +*/ + Line::Line() { this->line.clear(); this->line.reserve(4); @@ -10,7 +16,7 @@ Line::Line(size_t length) { this->line.reserve(length); } -void Line::processLine() { +void Line::process() { std::vector result; Tile pending = 0; bool hasPending = false; @@ -39,9 +45,56 @@ void Line::processLine() { result.push_back(pending); } - while (result.size() < sourceLine.size()) { + while (result.size() < this->line.size()) { result.push_back(0); } - return result; + this->line = result; +} + +// base methods +void Line::push_back(Tile tile) { + this->line.push_back(tile); +} + +size_t Line::size() { + return this->line.size(); +} + +size_t Line::size() const { + return this->line.size(); +} + +// overloadings +Tile& Line::operator[](size_t index) { + return this->line[index]; +} + +const Tile& Line::operator[](size_t index) const { + return this->line[index]; +} + +bool Line::operator==(const Line &other) const { + return this->line == other.line && this->score == other.score; +} + +bool Line::operator!=(const Line &other) const { + return !(*this == other); +} + +// iterators +std::vector::iterator Line::begin() { + return this->line.begin(); +} + +std::vector::iterator Line::end() { + return this->line.end(); +} + +std::vector::const_iterator Line::begin() const { + return this->line.begin(); +} + +std::vector::const_iterator Line::end() const { + return this->line.end(); } \ No newline at end of file