Create 2048 Game using Python
FREE Online Courses: Transform Your Career – Enroll for Free!
2048 is a simple mathematics puzzle game. It is a really addictive and interesting game. Let’s build 2048 game with basic knowledge of Python.
About Python 2048 Game Project
The objective of the project is to develop a 2048 game using python tkinter. In this game, we have to press any one of four keys to move up, down, left, or right. When we press a key, the elements move in the direction of the respective key and if any two same numbers are in that same row or column they get added up.
Project Prerequisites
To develop this game we need a basic knowledge of this game and some models like tkinter, random and configparser.
- tkinter – for use Interface(UI)
- random – to generate random values
Download 2048 GameProject Code
Please download the full source code of 2048 game: Python 2048 Game Code
Steps to Build 2048 Game using Python
Let’s see the steps to create python 2048 Game.
- First we will import all the necessary modules.
- In the second step we will create the game window for the user.
- Then we will create a function to accept the keys from the user and move the cell according to it.
- Then create two functions one for game over and one for game won.
Project File Structure
Below is the structure of python 2048 game:
- Importing modules
- Creating display function
- Define Function
- Creating main function
1. Importing Modules for Python 2048 Game
We first import all the necessary libraries required for this project.
# ==== Importing all necessary libraries for PythonGeeks Python 2048 Game from tkinter import * import random
2. Create Display Window
First we’ll create the main class named Play_2048, in which we will first create an initiator function where we pass the root for the interface. With the help of root we will set the title, geometry, background image, frames and buttons for the interface.
# ==== creating main class class Play_2048(Tk): # ==== adding necessary class variables game_board = [] new_random_tiles = [2, 2, 2, 2, 2, 2, 4] score = 0 high_score = 0 game_score = 0 highest_score = 0 # ==== creating user window def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) # ==== create user interface self.game_score = StringVar(self) self.game_score.set("0") self.highest_score = StringVar(self) self.highest_score.set("0") # ==== adding new game , score and highest score option self.button_frame = Frame(self) self.button_frame.grid(row=2, column=0, columnspan=4) Button(self.button_frame, text="New Game", font=("times new roman", 15), command=self.new_game).grid(row=0, column=0) self.button_frame.pack(side="top") Label(self.button_frame, text="Score:", font=("times new roman", 15)).grid(row=0, column=1) Label(self.button_frame, textvariable=self.game_score, font=("times new roman", 15)).grid(row=0, column=2) Label(self.button_frame, text="Record:", font=("times new roman", 15)).grid(row=0, column=3) Label(self.button_frame, textvariable=self.highest_score, font=("times new roman", 15)).grid(row=0, column=4) self.canvas = Canvas(self, width=410, height=410, borderwidth=5, highlightthickness=0) self.canvas.pack(side="top", fill="both", expand="false") # ==== create new game self.new_game()
3. Define functions
a. new_tiles()
This function will add new tiles to the game window when we perform any movement in game. The tiles will have either number 2 or number 4 and the new generated tiles will have different colors for both the numbers.
# ==== add new tiles in python 2048 game def new_tiles(self): index = random.randint(0, 6) x = -1 y = -1 # ==== check while game is not over while self.full() == False: x = random.randint(0, 3) y = random.randint(0, 3) if (self.game_board[x][y] == 0): self.game_board[x][y] = self.new_random_tiles[index] x1 = y * 105 y1 = x * 105 x2 = x1 + 105 - 5 y2 = y1 + 105 - 5 num = self.game_board[x][y] if num == 2: self.square[x, y] = self.canvas.create_rectangle(x1, y1, x2, y2, fill="#e0f2f8", tags="rect", outline="", width=0) self.canvas.create_text((x1 + x2) / 2, (y1 + y2) / 2, font=("Arial", 36), fill="#f78a8a", text="2") elif num == 4: self.square[x, y] = self.canvas.create_rectangle(x1, y1, x2, y2, fill="#b8dbe5", tags="rect", outline="", width=0) self.canvas.create_text((x1 + x2) / 2, (y1 + y2) / 2, font=("Arial", 36), fill="#f78a8a", text="4") Break
b. full()
This function will check whether all the grid in the game is full or not. It will return either True or False.
# ==== showing game board def show_board(self): cellwidth = 105 cellheight = 105 self.square = {} for column in range(4): for row in range(4): x1 = column * cellwidth y1 = row * cellheight x2 = x1 + cellwidth - 5 y2 = y1 + cellheight - 5 num = self.game_board[row] if num == 0: self.show_number0(row, column, x1, y1, x2, y2) else: self.show_number(row, column, x1, y1, x2, y2, num)
c. show_board()
This function will show the game board. Each number in the game window will have a separate color. The numbers in the game board are 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 and 2048.
# ==== showing game board in python 2048 game def show_board(self): cellwidth = 105 cellheight = 105 self.square = {} for column in range(4): for row in range(4): x1 = column * cellwidth y1 = row * cellheight x2 = x1 + cellwidth - 5 y2 = y1 + cellheight - 5 num = self.game_board[row] if num == 0: self.show_number0(row, column, x1, y1, x2, y2) else: self.show_number(row, column, x1, y1, x2, y2, num)
d. show_number0()
This function will have to show the color of the grid when there is no number on it.
# ==== show board block when it is empty def show_number0(self, row, column, a, b, c, d): self.square[row, column] = self.canvas.create_rectangle(a, b, c, d, fill="#f5f5f5", tags="rect", outline="")
e. show_number()
This function will show the color of the grid and number as respect to the different numbers.
# ==== show board number def show_number(self, row, column, a, b, c, d, num): bg_color = {'2': '#eee4da', '4': '#ede0c8', '8': '#edc850', '16': '#edc53f', '32': '#f67c5f', '64': '#f65e3b', '128': '#edcf72', '256': '#edcc61', '512': '#f2b179', '1024': '#f59563', '2048': '#edc22e',} color = {'2': '#776e65', '4': '#f9f6f2', '8': '#f9f6f2', '16': '#f9f6f2', '32': '#f9f6f2', '64': '#f9f6f2', '128': '#f9f6f2', '256': '#f9f6f2', '512': '#776e65', '1024': '#f9f6f2', '2048': '#f9f6f2', } self.square[row, column] = self.canvas.create_rectangle(a, b, c, d, fill=bg_color[str(num)], tags="rect", outline="") self.canvas.create_text((a + c) / 2, (b + d) / 2, font=("Arial", 36), fill=color[str(num)], text=str(num))
f. moves()
This function will accept the different events performed by the user and perform the movement of blocks of grid as per the event. The events given by the user are ‘UP’, ‘DOWN’, ‘LEFT’, and ‘RIGHT’.
# ==== moves by user def moves(self, event): if event.keysym == 'Down': for j in range(0, 4): shift = 0 for i in range(3, -1, -1): if self.game_board[i][j] == 0: shift += 1 else: if i - 1 >= 0 and self.game_board[i - 1][j] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i - 1][j] = 0 elif i - 2 >= 0 and self.game_board[i - 1][j] == 0 and self.game_board[i - 2][j] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i - 2][j] = 0 elif i == 3 and self.game_board[2][j] + self.game_board[1][j] == 0 and self.game_board[0][j] == self.game_board[3][ j]: self.game_board[3][j] *= 2 self.score += self.game_board[3][j] self.game_board[0][j] = 0 if shift > 0: self.game_board[i + shift][j] = self.game_board[i][j] self.game_board[i][j] = 0 self.show_board() self.new_tiles() self.game_over() elif event.keysym == 'Right': for i in range(0, 4): shift = 0 for j in range(3, -1, -1): if self.game_board[i][j] == 0: shift += 1 else: if j - 1 >= 0 and self.game_board[i][j - 1] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i][j - 1] = 0 elif j - 2 >= 0 and self.game_board[i][j - 1] == 0 and self.game_board[i][j - 2] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i][j - 2] = 0 elif j == 3 and self.game_board[i][2] + self.game_board[i][1] == 0 and self.game_board[0][j] == self.game_board[3][ j]: self.game_board[i][3] *= 2 self.score += self.game_board[i][3] self.game_board[i][0] = 0 if shift > 0: self.game_board[i][j + shift] = self.game_board[i][j] self.game_board[i][j] = 0 self.show_board() self.new_tiles() self.game_over() elif event.keysym == 'Left': for i in range(0, 4): shift = 0 for j in range(0, 4): if self.game_board[i][j] == 0: shift += 1 else: if j + 1 < 4 and self.game_board[i][j + 1] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i][j + 1] = 0 elif j + 2 < 4 and self.game_board[i][j + 1] == 0 and self.game_board[i][j + 2] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i][j + 2] = 0 elif j == 0 and self.game_board[i][1] + self.game_board[i][2] == 0 and self.game_board[i][3] == self.game_board[i][ 0]: self.game_board[i][0] *= 2 self.score += self.game_board[i][0] self.game_board[i][3] = 0 if shift > 0: self.game_board[i][j - shift] = self.game_board[i][j] self.game_board[i][j] = 0 self.show_board() self.new_tiles() self.game_over() elif event.keysym == 'Up': for j in range(0, 4): shift = 0 for i in range(0, 4): if self.game_board[i][j] == 0: shift += 1 else: if i + 1 < 4 and self.game_board[i + 1][j] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i + 1][j] = 0 elif i + 2 < 4 and self.game_board[i + 1][j] == 0 and self.game_board[i + 2][j] == self.game_board[i][j]: self.game_board[i][j] *= 2 self.score += self.game_board[i][j] self.game_board[i + 2][j] = 0 elif i == 0 and self.game_board[1][j] + self.game_board[2][j] == 0 and self.game_board[3][j] == self.game_board[0][ j]: self.game_board[0][j] *= 2 self.score += self.game_board[0][j] self.game_board[3][j] = 0 if shift > 0: self.game_board[i - shift][j] = self.game_board[i][j] self.game_board[i][j] = 0 self.show_board() self.new_tiles() self.game_over() self.game_score.set(str(self.score)) if self.score > self.high_score: self.high_score = self.score self.highest_score.set(str(self.high_score))
g. new_game()
This function will create a new game for the user. It will display a fresh game with the last highest score of the user.
# ==== to create new python 2048 game def new_game(self): self.score = 0 self.game_score.set("0") self.game_board = [] self.game_board.append([0, 0, 0, 0]) self.game_board.append([0, 0, 0, 0]) self.game_board.append([0, 0, 0, 0]) self.game_board.append([0, 0, 0, 0]) while True: x = random.randint(0, 3) y = random.randint(0, 3) if (self.game_board[x][y] == 0): self.game_board[x][y] = 2 break index = random.randint(0, 6) while self.full() == False: x = random.randint(0, 3) y = random.randint(0, 3) if (self.game_board[x][y] == 0): self.game_board[x][y] = self.new_random_tiles[index] break self.show_board()
h. game_over()
This function will check for game over, it will return True if the game is over and display a new empty grid window displaying “GAME OVER”.
# ==== check for game over def game_over(self): for i in range(0, 4): for j in range(0, 4): if (self.game_board[i][j] == 2048): self.game_won() for i in range(0, 4): for j in range(0, 4): if (self.game_board[i][j] == 0): return False for i in range(0, 4): for j in range(0, 3): if (self.game_board[i][j] == self.game_board[i][j + 1]): return False for j in range(0, 4): for i in range(0, 3): if self.game_board[i][j] == self.game_board[i + 1][j]: return False gameover = [["G", "A", "M", "E", ], ["", "", "", ""], ["O", "V", "E", "R"], ["", "", "", ""]] cellwidth = 105 cellheight = 105 self.square = {} for column in range(4): for row in range(4): a = column * cellwidth b = row * cellheight c = a + cellwidth - 5 d = b + cellheight - 5 self.square[row, column] = self.canvas.create_rectangle(a, b, c, d, fill="#ede0c8", tags="rect", outline="") self.canvas.create_text((a + c) / 2, (b + d) / 2, font=("Arial", 36), fill="#494949", text=gameover[row]) return True
h. game_won()
This function will check for a game won and condition for game won is the user has to make a grid of value 2048, then it will return True and display a new empty grid window displaying “GAMEWON!”.
# ==== check for game won def game_won(self): gameover = [["Y", "O", "U", "", ], ["", "", "", ""], ["W", "O", "N", "!"], ["", "", "", ""]] cellwidth = 105 cellheight = 105 self.square = {} for column in range(4): for row in range(4): a = column * cellwidth b = row * cellheight c = a + cellwidth - 5 d = b + cellheight - 5 self.square[row, column] = self.canvas.create_rectangle(a, b, c, d, fill="#ede0c8", tags="rect", outline="") self.canvas.create_text((a + c) / 2, (b + d) / 2, font=("Arial", 36), fill="#494949", text=gameover[row])
4. Creating the main function
In the main function, the main window of tkinter is made and the creation of objects for the main class is done. In this function, we will pass the user moves, title of our project, size of game window.
if __name__ == "__main__": # ==== preparing main window app = Play_2048() app.bind_all('<Key>', app.moves) app.wm_title("2048 by PythonGeeks") app.minsize(430, 470) app.mainloop()
Python 2048 Project Output
Summary
YAY!! We have successfully developed the 2048 game using python and the tkinter library. We learn how to use tkinter to make GUI. This tutorial is divided into various tasks.
I hope you enjoyed building this project using this tutorial at PythonGeeks.