Create 2048 Game in Python

Python course with 57 real-time projects - Learn Python

This is a popular sliding tile puzzle for single player. Let’s start developing this amazing game on our own. While making the 2048 project in Python, we will learn various concepts. Let’s start developing this cool project.

About 2048 Game

In this project the player has to slide the numbered tiles on the grid to create a tile with number 2048. The player can continue to play the game after reaching the 2048 tile and can create tiles with larger numbers. The player will also get points while playing the game.

Python 2048 Game project

The objective of this project is to implement 2048 Game using python. We need a pygame module to develop this project. We also need to import sys, time, constants and random modules.

Project Prerequisites

To develop this Python 2048 game project knowledge of pygame modules is a must. You also need the knowledge of python to complete this project.

Download 2048 Game

Please download source code of python 2048 Game: 2048 Game in Python

Project File Structure

Steps to follow to built python 2048 Game:

1.Install pygame module
2. Importing Modules
3. Initializing game window
4.Defining colors and function
5.Defining Main function
6.Function to check whether movement of tiles is possible or not
7.Defining function for merging tiles
8.Other functions

1. Install pygame module:

Multimedia applications like games are made by pygame which is a free and open source python programming language library. Pygame consists of sound libraries and computer graphics that are designed to be used with python. Installation of pygame is mandatory to start the project. Write the following code on your command prompt to install pygame.

pip install pygame

2. Importing Modules:

import pygame,sys,time
from pygame.locals import *
from constants import *
from random import *

Code Explanation:

a. sys: Different parts of the python runtime environment are manipulated with the sys module.
b. time: It provides functions to work with time.
c. pygame.locals: Various constants that are used by pygame are available in this module.
d. Random: pseudo random numbers are generated with this module.

3. Initializing game window:

pygame.init()
 
surface = pygame.display.set_mode((400,500),0,32)
pygame.display.set_caption("2048 Game by DataFlair")
 
font = pygame.font.SysFont("monospace",40)
fontofscore = pygame.font.SysFont("monospace",30)
 
tileofmatrix = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
undomatrix = []

Code Explanation:

a. pygame.init(): All the imported pygame modules are initialized with pygame.init.
b. set_mode(): It sets up the screen for display.
c. set_caption(): It displays the title in the parentheses on the top of the pygame window.
d. pygame.font.SysFont(): It loads the font from the system with the help of pygame.
e. tileofmatrix: It’s a nested list that will initially have value 0 on every tile.

4. Defining colors and function:

black = (0,0,0)
red = (255,0,0)
orange = (255,152,0)
deeporange = (255,87,34)
brown = (121,85,72)
green = (0,128,0)
lgreen = (139,195,74)
teal = (0,150,136)
blue  = (33,150,136)
purple = (156,39,176)
pink = (234,30,99)
deeppurple = (103,58,183)
 
 
colordict = {
    0:black,
    2:red,
    4:green,
    8:purple,
    16:deeppurple,
    32:deeporange,
    64:teal,
    128:lgreen,
    256:pink,
    512:orange,
    1024:black,
    2048:brown
}
 
def getcolor(i):
    return colordict[i]

Code Explanation:

a. getcolor(): It is a function that returns a dictionary of colours.
b. colordict: It is a dictionary of colours.

5. Defining Main function:

def mainfunction(fromLoaded = False):
    
    if not fromLoaded:
        placerandomtile()
        placerandomtile()
    printmatrix()
 
 
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            
            if checkIfCanGo() == True:
                if event.type == KEYDOWN:
                    if isArrow(event.key):
                        rotations = getrotations(event.key)
                        addToUndo()
                        for i in range(0,rotations):
                            rotatematrixclockwise()
 
                        if canmove():
                            movetiles()
                            mergetiles()
                            placerandomtile()
 
                        for j in range(0,(4-rotations)%4):
                            rotatematrixclockwise()
                            
                        printmatrix()
            else: # just checking wait
                gameover()
 
            if event.type == KEYDOWN:
                global sizeofboard
 
                if event.key == pygame.K_r:
                 
                    reset()
                if 50<event.key and 56 > event.key:
                    
                    sizeofboard = event.key - 48
                    reset()
                if event.key == pygame.K_s:
                   
                    savegame()
                elif event.key == pygame.K_l:
                    loadgame()
                    
                elif event.key == pygame.K_u:
                    undo()
                   
        pygame.display.update()

Code Explanation:

a. get(): List of all the unprocessed events are returned with get().
b. quit: It exits a python program.
c. KEYDOWN: It detects if a key is pressed or not.
d. K_r: If key r is pressed reset() function is called to reset the game.
e. K_s: If key s is pressed savegame() function is called which saves the game.
f. K_l:If key l is pressed, a loadgame() function is called which loads the game.
g. K_u: If key u is pressed undo() function is called.

6. Function to check whether movement of tiles is possible or not:

def canmove():
    for i in range(0,sizeofboard):
        for j in range(1,sizeofboard):
            if tileofmatrix[i][j-1] == 0 and tileofmatrix[i][j] > 0:
                return True 
            elif (tileofmatrix[i][j-1] == tileofmatrix[i][j]) and tileofmatrix[i][j-1] != 0:
                return True
    return False
    # This module moves 
def movetiles():
    for i in range(0,sizeofboard):
        for j in range(0,sizeofboard-1):
            
            while tileofmatrix[i][j] == 0 and sum(tileofmatrix[i][j:]) > 0:
                for k in range(j,sizeofboard-1):
                   tileofmatrix[i][k] = tileofmatrix[i][k+1]
                tileofmatrix[i][sizeofboard-1] = 0

Code Explanation:

a. canmove(): This function checks whether the movement of tiles is possible or not.
b. movetiles(): It helps in the movement of tiles.
c. sum(): It calculates the sum of the numbers.

7. Defining function for merging tiles:

def mergetiles():
    global totalpoints
 
    for i in range(0,sizeofboard):
        for k in range(0,sizeofboard-1):
            if tileofmatrix[i][k] == tileofmatrix[i][k+1] and tileofmatrix[i][k] != 0:
                tileofmatrix[i][k] = tileofmatrix[i][k]*2
                tileofmatrix[i][k+1] = 0                 totalpoints+= tileofmatrix[i][k]
                movetiles()

Code Explanation:

a. mergetiles(): This function helps in merging the tiles.
b. range(): It helps in performing an action for a specific number of times.

8. Other functions:

def floor(n):
    return int(n - (n % 1 ))  
def printmatrix():
        surface.fill(black)
        global sizeofboard
        global totalpoints
 
        for i in range(0,sizeofboard):
            for j in range(0,sizeofboard):
                pygame.draw.rect(surface,getcolor(tileofmatrix[i][j]),(i*(400/sizeofboard),j*(400/sizeofboard)+100,400/sizeofboard,400/sizeofboard))
                label = font.render(str(tileofmatrix[i][j]),1,(255,255,255))
                label2 = fontofscore.render("YourScore:"+str(totalpoints),1,(255,255,255))
                surface.blit(label,(i*(400/sizeofboard)+30,j*(400/sizeofboard)+130))
                surface.blit(label2,(10,20))
def checkIfCanGo():
    for i in range(0,sizeofboard ** 2):         if tileofmatrix[floor(i/sizeofboard)][i%sizeofboard] == 0:
            return True
    
    for i in range(0,sizeofboard):
        for j in range(0,sizeofboard-1):
            if tileofmatrix[i][j] == tileofmatrix[i][j+1]:
                return True
            elif tileofmatrix[j][i] ==tileofmatrix[j+1][i]:
                return True
    return False
def convertToLinearMatrix():
 
    mat = []
    for i in range(0,sizeofboard ** 2):
        mat.append(tileofmatrix[floor(i/sizeofboard)][i%sizeofboard])
 
    mat.append(totalpoints)
    return mat
def addToUndo():
    undomatrix.append(convertToLinearMatrix())   
def rotatematrixclockwise():
    for i in range(0,int(sizeofboard/2)):
        for k in range(i,sizeofboard- i- 1):
            temp1 = tileofmatrix[i][k]
            temp2 = tileofmatrix[sizeofboard - 1 - k][i]
            temp3 = tileofmatrix[sizeofboard- 1 - i][sizeofboard - 1 - k]
            temp4 = tileofmatrix[k][sizeofboard- 1 - i]
 
            tileofmatrix[sizeofboard- 1 - k][i] = temp1
            tileofmatrix[sizeofboard - 1 - i][sizeofboard - 1 - k] = temp2
            tileofmatrix[k][sizeofboard - 1 - i] = temp3
            tileofmatrix[i][k] = temp4
 
def gameover():
    global totalpoints
 
    surface.fill(black)
 
    label = font.render("gameover",1,(255,255,255))
    label2 =font.render("score : "+str(totalpoints),1,(255,255,255))
    label3 = font.render("press 'R' to play again",1,(255,255,255))
 
    surface.blit(label,(50,100))
    surface.blit(label2,(50,200))
    surface.blit(label3,(50,300))
 
 
def reset():
    global totalpoints
    global tileofmatrix
 
    totalpoints= 0
    surface.fill(black)
    tileofmatrix = [[0 for i in range(0,sizeofboard)] for j in range(0,sizeofboard) ]
    mainfunction()
 
def savegame():
    f = open("savedata","w")
 
    line1 = " ".join([str(tileofmatrix[floor(x/sizeofboard)][x%sizeofboard]) for x in range(0,sizeofboard ** 2)])
    f.write(line1+"\n")
    f.write(str(sizeofboard)+"\n")
    f.write(str(totalpoints))
    f.close
 
def undo():
    if len(undomatrix) > 0:
        mat = undomatrix.pop()
 
        for i in range(0,sizeofboard ** 2):
            tileofmatrix[floor(i/sizeofboard)][i%sizeofboard] = mat[i]
        global totalpoints
        totalpoints = mat[sizeofboard ** 2]
 
        printmatrix()
 
def loadgame():
    global totalpoints
    global sizeofboard
    global tilematrix
 
    f = open("savedata","r")
 
    mat = (f.readline()).split(' ',sizeofboard ** 2)
    sizeofboard = int(f.readline())
    totalpoints= int(f.readline())
 
    for i in range(0,sizeofboard ** 2):
        tileofmatrix[floor(i/sizeofboard)][i%sizeofboard] = int(mat[i])
 
    f.close()
 
    mainfunction(True)
 
 
 
def isArrow(k):
    return (k == pygame.K_UP or k == pygame.K_DOWN or k == pygame.K_LEFT or k == pygame.K_RIGHT)
 
def getrotations(k):
    if k == pygame.K_UP:
        return 0
    elif k == pygame.K_DOWN:
        return 2 
    elif k == pygame.K_LEFT:
        return 1
    elif k == pygame.K_RIGHT:
        return 3
mainfunction()

Code Explanation:
a. floor(): It gets the floor value of a value passed in the function.
b. printmatrix(): It prints the matrix on the screen.
c. fill(): It fills the shape with the colour in the parentheses.
d. convertToLinearMatrix(): This module returns a matrix.
e. gameover(): When there is no place in the matrix or the player is out of moves the game gets over.
f. reset(): It resets the game.
g. savegame(): It saves the state of moves.
h. undo(): This function gets the last move.
i. loadgame(): It loads the game for the player.
j. isArrow(): It finds out which key is pressed by the user.
k. K_UP: If the up arrow key is clicked, the function returns 0.
l. K_DOWN:If the down arrow key is clicked, the function returns 2.
m. K_LEFT:If the left arrow key is clicked, the function returns 1.
n. K_RIGHT:If the right arrow key is clicked, the function returns 3.
o. mainfunction: It calls the main function.

Python 2048 Game Output:

python 2048 game output

Summary:

We have successfully developed 2048 Game in python with the help of pygame module and python.

If you are Happy with DataFlair, do not forget to make us happy with your positive feedback on Google

follow dataflair on YouTube

3 Responses

  1. Roshan Dubey says:

    Not working
    Error: Placerandomtile() is not defined at line 52

  2. Simon Krome says:

    The definition of “def placerandomtile” is mission after the seventh step.

    This is missing:

    def placerandomtile():
    c = 0
    for i in range(0,sizeofboard):
    for j in range(0,sizeofboard):
    if tileofmatrix[i][j] == 0:
    c += 1

    k = floor(random() * sizeofboard* sizeofboard)
    print(“click”)

    while tileofmatrix[floor(k/sizeofboard)][k%sizeofboard] != 0:
    k = floor(random() * sizeofboard * sizeofboard)

    tileofmatrix[floor(k/sizeofboard)][k%sizeofboard] = 2

Leave a Reply

Your email address will not be published. Required fields are marked *