diff --git a/Game.cpp b/Game.cpp index 1f5aa77..c8df902 100644 --- a/Game.cpp +++ b/Game.cpp @@ -6,40 +6,44 @@ #include class Game { - private: + protected: + std::vector> AddNew(std::vector> m); + std::vector> Transpose(std::vector> m); + std::vector> MergeUp(std::vector> m); + std::vector> CompressUp(std::vector> m); + std::vector> HamburgerFlip(std::vector> m); public: std::vector> state; int score; int highest_tile; - - Game() : state{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, score(0), highest_tile(0) { } - bool CanContinue(); + const int DIM; + + Game(int d=4) : DIM(d), score(0), highest_tile(0), state{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}} { + state = AddNew(state); + state = AddNew(state); + } + bool CanContinue(std::vector> m); int* PossibleMoves(); - void Transpose(); - void AddNew(); - void MergeUp(); - void CompressUp(); - void HamburgerFlip(); - void Up(); - void Left(); - void Right(); - void Down(); + std::vector> Up(); + std::vector> Left(); + std::vector> Right(); + std::vector> Down(); }; -void Game::AddNew() { +std::vector> Game::AddNew(std::vector> m) { // Initialize rng device with random seed std::random_device rd; std::mt19937 rng(rd()); - std::uniform_int_distribution<> pos_dist(0, 3); + std::uniform_int_distribution<> pos_dist(0, DIM-1); // Generating a random position // TODO: FIND A BETTER METHOD OF GETTING A RANDOM EMPTY TILE int x = pos_dist(rng); int y = pos_dist(rng); - while(state[x][y] != 0) { + while(m[x][y] != 0) { // std::cout << "Need to find a new position" << std::endl; x = pos_dist(rng); y = pos_dist(rng); @@ -48,20 +52,21 @@ void Game::AddNew() { // Generating a random value of 2 or 4 (weighted probability) std::uniform_int_distribution<> val_dist(0, 9); if (val_dist(rng) > 0) { - state[x][y] = 2; + m[x][y] = 2; } else { - state[x][y] = 4; + m[x][y] = 4; } + return m; } -bool Game::CanContinue() { - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (state[i][j] == 0) +bool Game::CanContinue(std::vector> m) { + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + if (m[i][j] == 0) return true; - if ((i < 3 && state[i][j] == state[i + 1][j]) || - (j < 3 && state[i][j] == state[i][j + 1])) + if ((i < (DIM-1) && m[i][j] == m[i + 1][j]) || + (j < (DIM-1) && m[i][j] == m[i][j + 1])) return true; } } @@ -75,123 +80,131 @@ int* Game::PossibleMoves() { int* move_list = {}; // left_copy = - Transpose(); + // Transpose(); return move_list; } -void Game::MergeUp() { - for (int col = 0; col < 4; col++) { +std::vector> Game::MergeUp(std::vector> m) { + std::vector> state_cpy = m; + for (int col = 0; col < DIM; col++) { std::vector merged_column; - for (int i = 0; i < 4; i++) { - if (state[i][col] != 0) { - merged_column.push_back(state[i][col]); + for (int i = 0; i < DIM; i++) { + if (m[i][col] != 0) { + merged_column.push_back(m[i][col]); } } - while (merged_column.size() < 4) { + while (merged_column.size() < DIM) { merged_column.push_back(0); } - for (int i = 0; i < 4; i++) { - state[i][col] = merged_column[i]; + for (int i = 0; i < DIM; i++) { + state_cpy[i][col] = merged_column[i]; } } + return state_cpy; } -void Game::CompressUp() { - for (int col = 0; col < 4; col++) { +std::vector> Game::CompressUp(std::vector> m) { + std::vector> state_cpy = m; + for (int col = 0; col < DIM; col++) { std::vector compressed_column; - if (state[0][col] == state[1][col]) { - compressed_column.push_back(state[0][col] * 2); - score += state[0][col] * 2; - if (state[2][col] == state[3][col]) { - compressed_column.push_back(state[2][col] * 2); - compressed_column.push_back(0); - compressed_column.push_back(0); - score += state[2][col] * 2; + if (m[0][col] == m[1][col]) { + compressed_column.push_back(m[0][col] * 2); + score += m[0][col] * 2; + if (m[2][col] == m[3][col]) { + compressed_column.push_back(m[2][col] * 2); + score += m[2][col] * 2; } else { - compressed_column.push_back(state[2][col]); - compressed_column.push_back(state[3][col]); - compressed_column.push_back(0); + compressed_column.push_back(m[2][col]); + compressed_column.push_back(m[3][col]); } } - else if (state[1][col] == state[2][col]) { - compressed_column.push_back(state[0][col]); - compressed_column.push_back(state[1][col] * 2); - compressed_column.push_back(state[3][col]); - compressed_column.push_back(0); - score += state[1][col] * 2; + else if (m[1][col] == m[2][col]) { + compressed_column.push_back(m[0][col]); + compressed_column.push_back(m[1][col] * 2); + compressed_column.push_back(m[3][col]); + score += m[1][col] * 2; } - else if (state[2][col] == state[3][col]) { - compressed_column.push_back(state[0][col]); - compressed_column.push_back(state[1][col]); - compressed_column.push_back(state[2][col] * 2); - compressed_column.push_back(0); - score += state[2][col] * 2; + else if (m[2][col] == m[3][col]) { + compressed_column.push_back(m[0][col]); + compressed_column.push_back(m[1][col]); + compressed_column.push_back(m[2][col] * 2); + score += m[2][col] * 2; } else { - compressed_column.push_back(state[0][col]); - compressed_column.push_back(state[1][col]); - compressed_column.push_back(state[2][col]); - compressed_column.push_back(state[3][col]); + compressed_column.push_back(m[0][col]); + compressed_column.push_back(m[1][col]); + compressed_column.push_back(m[2][col]); + compressed_column.push_back(m[3][col]); } - for (int i = 0; i < 4; i++) { - state[i][col] = compressed_column[i]; + while(compressed_column.size() < DIM) { + compressed_column.push_back(0); + } + for (int i = 0; i < DIM; i++) { + state_cpy[i][col] = compressed_column[i]; } } + return state_cpy; } -void Game::HamburgerFlip() { +std::vector> Game::HamburgerFlip(std::vector> m) { std::vector> flipped_state = {{}, {}, {}, {}}; - for (int row = 3, i = 0; row >= 0; row--, i++) { - flipped_state[i] = state[row]; + for (int row = (DIM-1), i = 0; row >= 0; row--, i++) { + flipped_state[i] = m[row]; } - state = flipped_state; + return flipped_state; } -void Game::Transpose() { +std::vector> Game::Transpose(std::vector> m) { std::vector> transposed_state = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - transposed_state[i][j] = state[j][i]; + for (int i = 0; i < DIM; i++) { + for (int j = 0; j < DIM; j++) { + transposed_state[i][j] = m[j][i]; } } - // TODO: MAKE THIS RETURN TRANSPOSED STATE INSTEAD FOR MORE FLEXIBILITY??? - state = transposed_state; + return transposed_state; } -void Game::Up() { +std::vector> Game::Up() { std::vector> prev_state = state; - MergeUp(); - CompressUp(); + prev_state = MergeUp(prev_state); + prev_state = CompressUp(prev_state); if (state != prev_state) { - AddNew(); + prev_state = AddNew(prev_state); } + return prev_state; } -void Game::Down() { - HamburgerFlip(); - Up(); - HamburgerFlip(); +std::vector> Game::Down() { + std::vector> prev_state = state; + prev_state = HamburgerFlip(prev_state); + prev_state = Up(); + prev_state = HamburgerFlip(prev_state); + return prev_state; } -void Game::Left() { - Transpose(); - Up(); - Transpose(); +std::vector> Game::Left() { + std::vector> prev_state = state; + prev_state = Transpose(prev_state); + prev_state = Up(); + prev_state = Transpose(prev_state); + return prev_state; } -void Game::Right() { - Transpose(); - Down(); - Transpose(); +std::vector> Game::Right() { + std::vector> prev_state = state; + prev_state = Transpose(prev_state); + prev_state = Down(); + prev_state = Transpose(prev_state); + return prev_state; } std::ostream& operator<<(std::ostream &stream, Game &game) { std::string str = ""; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { + for (int i = 0; i < game.DIM; i++) { + for (int j = 0; j < game.DIM; j++) { str += std::to_string(game.state[i][j]) + " "; } str += "\n"; @@ -200,36 +213,27 @@ std::ostream& operator<<(std::ostream &stream, Game &game) { } int main(int argc, char** argv) { - std::random_device rd; - std::mt19937 rng(rd()); - std::uniform_int_distribution<> move_dist(0, 3); Game game = Game(); - - game.AddNew(); - game.AddNew(); - std::cout << game; - // game.HamburgerFlip(); - // std::cout << game; - // std::vector v1 = {0, 1, 2, 3}; - // std::vector v2 = {0, 1, 2, 3}; - // std::cout << (v1 == v2) << std::endl; - while(game.CanContinue()) { + std::random_device rd; + std::mt19937 rng(rd()); + std::uniform_int_distribution<> move_dist(0, 3); + while(game.CanContinue(game.state)) { int random_number = move_dist(rng); if (random_number == 0) { - game.Up(); + game.state = game.Up(); } else if (random_number == 1) { - game.Down(); + game.state = game.Down(); } else if (random_number == 2) { - game.Right(); + game.state = game.Right(); } else { - game.Left(); + game.state = game.Left(); } - std::cout << game; + std::cout << game << std::endl; } return 0;