2048 is perhaps one of the most addictive mathematical puzzle games. For starters, it is played on a 4 × 4 game board which begins with an initial configuration of two tiles, of value 2 or 4, placed at arbitrary locations on the grid.
The player then selects to move Up, Down, Left, or Right. Each move shifts all tiles on the grid in the direction chosen. If two adjacent tiles have the same value, they combine, and the single resulting tile after the combination will be the sum (twice). Following the player’s move, a tile of value 2 or 4 will be generated at a random position on the board.
The goal of the game is to combine equally-valued tiles to reach the 2048 tile without getting stuck.
HOW I CODED 2048 ( Source code at the end of this page)
THE LOOP
- Display the grid.
- Take direction input.
- Check for game-over.
- Update the grid.
- Spawn a new tile.
- Refresh the grid.
LAYOUT
First thing you notice is that the game is basically a 4×4 matrix, a two dimensional array. Initialize all elements in it to zero. But then the empty tiles do not display ‘0’ on the game, so while printing the array elements, if the element is zero, print a space.
INPUT WITHOUT PRESSING ENTER KEY
You don’t want to press enter after every key press, a quick and easy way would be to modify the Linux Terminal behavior using 2 system functions. ( Beware, System() functions are vulnerable. Read here )
system("stty raw"); cin>>control; system("stty cooked");
ESSENTIAL VARIABLES AND FUNCTIONS
> We require 2 grids, one that keeps the current state of the game ( current grid ) and another that keeps the previous state , i.e a move before ( backup grid ). The backup grid serves 2 purposes:
- For the UNDO functionality, resuming to the previous state.
- To check if the grid moves.
> Random function to generate random positions ( rows and columns ) for the initial two tiles on the board and for the further tiles which will be generated on each move. The thing to note here is that probability of occurrence of 4 is less than that of 2.
> Greatest function to find the greatest tile in the grid at any state ( max tile ).
MOVING TILES IN THE GRID
// Case of Moving UP for(int i=0; i<4 ;i++) // Traverse from Top to bottom of a column for(int j=0; j<4 ;j++) { if(!grid[j][i]) // If tile is empty { for(int k=j+1; k<4 ;k++) // Traverse below to find a non-zero element if(grid[k][i]) { grid[j][i]=grid[k][i]; // Move the non-zero element to the empty tile grid[k][i]=0; // Assign the non-zero element with zero break; } } }
UPDATING THE GRID
- Check if adjacent tile is equal.
- Sum / double the tile(s) if they are equal.
// When moving UP if(grid[j][i]&&grid[j][i]==grid[j+1][i]) // Check Tile is non zero and { // adjacent tile is equal grid[j][i]+=grid[j+1][i]; // add to first element or double grid[j+1][i]=0; // assign second element with zero }
GAME OVER LOGIC
The game ends when
- Grid is full and a new tile cannot be spawned.
- The game is won, 2048 has been created.
To check whether the grid is full, check if all the elements are non-zero. Spawn mentioned below.
To check whether the game is won, check If the max tile is equal to the win (2048), display the win screen and update the win to win*2 ( 4096, 8192, 16384 …)
SPAWNING A NEW TILE
With every move, a new tile should be spawned in a random position under the condition that the selected direction moves at least 1 tile in the grid. So this is where the backup grid comes into use, before updating the grid :
- Check if the current grid is equal to the backup grid.
So that we know if at least one tile in the grid has moved. Then spawn a new tile in an empty cell.
SCORING ALGORITHM
Merging two lower tier blocks together will give you the score of the higher tier block (score of +8 gained from merging two 4’s). For any specific tile score, you have to add up all the scores from the lower tiers.
- Creating a 2 tile = +0pts
- Creating a 4 tile = 4 = +4pts
- Creating a 8 tile = 8 + 2×4 = +16pts
- Creating a 16 tile = 16 + 2×8 + 4×4 = +48pts
- Creating a 32 tile = 32 + 2×16 + 4×8 + 8×4 = +128pts …
Which can be simplified as
- Tile 21 = 0 x 21 = 0pts
- Tile 22 = 1 x 22 = 4pts
- Tile 23 = 2 x 23 = 16pts
- Tile 24 = 3 x 24 = 48pts
i.e tile-value times ( one less than ( log of tile-value to the base 2 ))
So the algorithm would be:
score+=(((log2(grid[j][i]))-1)*grid[j][i]);
UNDO
To perform UNDO operation, copy the backup grid to the current grid.
RANDOM GENERATION
Make the computer play the game on its own ! For that, remove the input call and create a char array with all the four direction keys ( w,a,s,d ) and choose a key in random. But if you’ve played 2048 long enough, you’d know that skipping a direction is the best strategy, so choose any 3 directions.
char keys[]="wad"; input=keys[rand()%3+0;]; // this function chooses 0,1 or 2 randomly // assigns key in that index to input variable
SOURCE CODE
CPP here C will be posted soon
Wow.. really awesome page. Hope the developer makes more codes like this.
LikeLiked by 1 person
superbe ça ! j’adore ce site internet, bravo tout simplement.
LikeLiked by 1 person
merci monsieur !
LikeLike
Shouldn’t here be a header code too? I tried to use the program and see how it works, but it says, that the file unistd.h is missing.
LikeLike
Hey, the header comes with all unix OSs. So I’m guessing you are on Windows. In any case, I’ve used this header just to create a delay for new numbers popping up after each move, using the usleep() function. Just comment the header and the instances of the usleep() function. ( Comment these three lines in the source code 3,104,460 )
LikeLike
YOU ARE TRULY GENIUS MAN
LikeLike
Do any of you have this game programmed in a C language?
LikeLike
If yes I would like to have the code posted for reference
LikeLike
Thanks a lot mate, it helped me when I was programming self-playing algorithm for 2048, so I didn’t have to start from scratch.
LikeLike
after i comment out the 3 lines usleeps and the header, i got an error. log2 identifier not found. Isn’t it already in math.h. why does it say that it’s not found.
LikeLike
Got the answer xD. my VS 2012 does not support c++11 > .<
LikeLike