#include <bits/stdc++.h>
using namespace std;
struct Game2048{
vector<vector<int>>board = vector<vector<int>>(4, vector<int>(4, 0));
int row[4] = {0, 0, -1, 1};
int col[4] = {-1, 1, 0, 0};
bool hasWon = 0, gameOver = 0;
bool validMove = 1;
Game2048(){
fillRandom();
fillRandom();
printBoard();
}
bool valid(int i, int j){
return i>=0 && i<4 && j>=0 && j<4;
}
bool swipeRight(vector<int>& v){
int lastInd = 4;
bool canMerge = 0;
bool hasMoved = 0;
for(int i=3; i>=0; --i)
if(v[i])
{
if(!canMerge || v[i] != v[lastInd]){
v[--lastInd] = v[i];
if(i != lastInd){
v[i] = 0;
hasMoved = 1;
}
canMerge = 1;
}
else{
v[lastInd]<<=1;
canMerge = 0;
v[i] = 0;
hasMoved = 1;
if(v[lastInd] == 2048)
hasWon = 1;
}
}
return hasMoved;
}
void finalTasks(bool hasMoved){
// check if board has valid move left
bool isValidMoveLeft = 0;
for(int i=0; i<4; ++i){
for(int j=0; j<4; ++j){
for(int k=0; k<4; ++k){
if(!board[i][j] || (valid(i+row[k], j+col[k]) && board[i+row[k]][j+col[k]] == board[i][j]))
{
isValidMoveLeft = 1;
break;
}
}
if(isValidMoveLeft) break;
}
if(isValidMoveLeft) break;
}
if(!isValidMoveLeft){
gameOver = 1;
return;
}
// check if move was valid
if(!hasMoved){
validMove = 0;
return;
}else{
validMove = 1;
}
fillRandom();
printBoard();
}
void fillRandom(){
vector<pair<int, int>>v;
for(int i=0; i<4; ++i){
for(int j=0; j<4; ++j){
if(!board[i][j])
v.push_back({i, j});
}
}
int ind = rand()%v.size();
bool val = rand()%2;
board[v[ind].first][v[ind].second] = (val ? 2 : 4);
}
void up(){
bool hasMoved = 0;
vector<int>v(4);
for(int j=0; j<4; ++j){
for(int i=0; i<4; ++i){
v[3-i] = board[i][j];
}
if(swipeRight(v))
hasMoved = 1;
for(int i=0; i<4; ++i){
board[i][j] = v[3-i];
}
}
finalTasks(hasMoved);
}
void down(){
bool hasMoved = 0;
vector<int>v(4);
for(int j=0; j<4; ++j){
for(int i=0; i<4; ++i){
v[i] = board[i][j];
}
if(swipeRight(v))
hasMoved = 1;
for(int i=0; i<4; ++i){
board[i][j] = v[i];
}
}
finalTasks(hasMoved);
}
void left(){
bool hasMoved = 0;
vector<int>v(4);
for(int i=0; i<4; ++i){
for(int j=0; j<4; ++j){
v[3-j] = board[i][j];
}
if(swipeRight(v))
hasMoved = 1;
for(int j=0; j<4; ++j){
board[i][j] = v[3-j];
}
}
finalTasks(hasMoved);
}
void right(){
bool hasMoved = 0;
vector<int>v(4);
for(int i=0; i<4; ++i){
for(int j=0; j<4; ++j){
v[j] = board[i][j];
}
if(swipeRight(v))
hasMoved = 1;
for(int j=0; j<4; ++j){
board[i][j] = v[j];
}
}
finalTasks(hasMoved);
}
void printBoard(){
for(int i=0; i<4; ++i){
for(int j=0; j<4; ++j){
if(board[i][j] == 0) cout<<".\t";
else cout<<board[i][j]<<"\t";
}
cout<<'\n';
}
cout<<"\n\n";
}
};
int main(){
srand(time(0));
cout<<"\nWelcome to 2048 Board Game\n";
cout<<"To make a move choose U,D,L,R or u,d,l,r\n";
cout<<"ALL THE BEST\n\n";
Game2048 game;
while(1){
cout<<"Enter your move : ";
char c;
cin>>c;
if(c == 'U' || c == 'u'){
game.up();
}else if(c == 'D' || c == 'd'){
game.down();
}else if(c == 'L' || c == 'l'){
game.left();
}else if(c == 'R' || c == 'r'){
game.right();
}else{
cout<<"Please enter valid input.\n\n";
continue;
}
if(game.hasWon){
cout<<"\n\nYOU WON THE GAME\n\n";
return 0;
}
if(game.gameOver){
cout<<"\n\nGAME OVER, YOU LOST\n\n";
return 0;
}
if(!game.validMove){
cout<<"\nINVALID MOVE\n\n";
}
}
return 0;
}