📜  Python 2048 游戏

📅  最后修改于: 2022-05-13 01:55:18.206000             🧑  作者: Mango

Python 2048 游戏

在本文中,我们将查看Python代码和逻辑来设计您在智能手机中经常玩的 2048 游戏。如果您对游戏不熟悉,强烈建议您先玩游戏,以便了解游戏的基本功能。

如何玩2048:

1.有一个4*4的网格,可以填任意数字。最初,两个随机单元格中填充了 2 个。休息单元是空的。

2.我们必须按四个键中的任何一个来向上、向下、向左或向右移动。当我们按下任意键时,单元格的元素会朝那个方向移动,这样如果在该特定行(向左或向右移动的情况下)或列(在向上和向下移动的情况下)中包含任何两个相同的数字,它们就会得到加起来,那个方向的极端单元格用那个数字填充自己,其余单元格再次变空。

3.在这个网格压缩之后,任何随机的空单元格都会被 2 填充。

4.按照上述过程,我们必须将元素加倍,并在任何单元格中生成 2048。如果我们能够做到这一点,我们就赢了。

5.但是如果在游戏过程中没有空单元格可以用新的 2 填充,那么游戏就结束了。

在上述过程中,您可以从 2048 游戏的图形用户界面中看到快照。但是所有的逻辑都在主代码中。因此,为了单独理解其背后的逻辑,我们可以假设上述网格是一个 4*4 矩阵(一个四行四列的列表)。您可以在下面看到上述游戏在没有 GUI 的情况下进行输入和输出的方式。

例子 :

Commands are as follows : 
'W' or 'w' : Move Up
'S' or 's' : Move Down
'A' or 'a' : Move Left
'D' or 'd' : Move Right
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 2, 0]
Press the command : a
GAME NOT OVER
[0, 0, 0, 2]
[0, 0, 0, 0]
[0, 0, 0, 0]
[2, 0, 0, 0]
Press the command : s
GAME NOT OVER
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 2, 0]
[2, 0, 0, 2]
Press the command : d
GAME NOT OVER
[0, 0, 0, 0]
[0, 0, 0, 0]
[2, 0, 0, 2]
[0, 0, 0, 4]
Press the command : a
GAME NOT OVER
[0, 2, 0, 0]
[0, 0, 0, 0]
[4, 0, 0, 0]
[4, 0, 0, 0]
Press the command : s
GAME NOT OVER
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[8, 2, 0, 2]
.
.
.
And the series of input output will go on till we lose or win!

编程方法:

  1. 我们将设计每个逻辑函数,例如我们正在执行左滑动,然后我们将通过反转矩阵并执行左滑动将其用于右滑动。
  2. 向上移动可以通过转置然后向左移动来完成。
  3. 下移可以通过转置右移来完成。
  4. 程序中的所有逻辑在评论中都有详细解释。强烈建议浏览所有评论。

我们下面有两个Python文件,一个是 2048.py 包含主要驱动程序代码,另一个是 logic.py 包含所有使用的函数。应在 2048.py 中导入 logic.py 以使用这些功能。只需将两个文件放在同一个文件夹中,然后运行 2048.py 即可完美运行。

逻辑.py

Python3
# logic.py to be
# imported in the 2048.py file
 
# importing random package
# for methods to generate random
# numbers.
import random
 
# function to initialize game / grid
# at the start
def start_game():
 
    # declaring an empty list then
    # appending 4 list each with four
    # elements as 0.
    mat =[]
    for i in range(4):
        mat.append([0] * 4)
 
    # printing controls for user
    print("Commands are as follows : ")
    print("'W' or 'w' : Move Up")
    print("'S' or 's' : Move Down")
    print("'A' or 'a' : Move Left")
    print("'D' or 'd' : Move Right")
 
    # calling the function to add
    # a new 2 in grid after every step
    add_new_2(mat)
    return mat
 
# function to add a new 2 in
# grid at any random empty cell
def add_new_2(mat):
 
   # choosing a random index for
   # row and column.
    r = random.randint(0, 3)
    c = random.randint(0, 3)
 
    # while loop will break as the
    # random cell chosen will be empty
    # (or contains zero)
    while(mat[r] != 0):
        r = random.randint(0, 3)
        c = random.randint(0, 3)
 
    # we will place a 2 at that empty
    # random cell.
    mat[r] = 2
 
# function to get the current
# state of game
def get_current_state(mat):
 
    # if any cell contains
    # 2048 we have won
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 2048):
                return 'WON'
 
    # if we are still left with
    # atleast one empty cell
    # game is not yet over
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 0):
                return 'GAME NOT OVER'
 
    # or if no cell is empty now
    # but if after any move left, right,
    # up or down, if any two cells
    # gets merged and create an empty
    # cell then also game is not yet over
    for i in range(3):
        for j in range(3):
            if(mat[i][j]== mat[i + 1][j] or mat[i][j]== mat[i][j + 1]):
                return 'GAME NOT OVER'
 
    for j in range(3):
        if(mat[3][j]== mat[3][j + 1]):
            return 'GAME NOT OVER'
 
    for i in range(3):
        if(mat[i][3]== mat[i + 1][3]):
            return 'GAME NOT OVER'
 
    # else we have lost the game
    return 'LOST'
 
# all the functions defined below
# are for left swap initially.
 
# function to compress the grid
# after every step before and
# after merging cells.
def compress(mat):
 
    # bool variable to determine
    # any change happened or not
    changed = False
 
    # empty grid
    new_mat = []
 
    # with all cells empty
    for i in range(4):
        new_mat.append([0] * 4)
         
    # here we will shift entries
    # of each cell to it's extreme
    # left row by row
    # loop to traverse rows
    for i in range(4):
        pos = 0
 
        # loop to traverse each column
        # in respective row
        for j in range(4):
            if(mat[i][j] != 0):
                 
                # if cell is non empty then
                # we will shift it's number to
                # previous empty cell in that row
                # denoted by pos variable
                new_mat[i][pos] = mat[i][j]
                 
                if(j != pos):
                    changed = True
                pos += 1
 
    # returning new compressed matrix
    # and the flag variable.
    return new_mat, changed
 
# function to merge the cells
# in matrix after compressing
def merge(mat):
     
    changed = False
     
    for i in range(4):
        for j in range(3):
 
            # if current cell has same value as
            # next cell in the row and they
            # are non empty then
            if(mat[i][j] == mat[i][j + 1] and mat[i][j] != 0):
 
                # double current cell value and
                # empty the next cell
                mat[i][j] = mat[i][j] * 2
                mat[i][j + 1] = 0
 
                # make bool variable True indicating
                # the new grid after merging is
                # different.
                changed = True
 
    return mat, changed
 
# function to reverse the matrix
# means reversing the content of
# each row (reversing the sequence)
def reverse(mat):
    new_mat =[]
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[i][3 - j])
    return new_mat
 
# function to get the transpose
# of matrix means interchanging
# rows and column
def transpose(mat):
    new_mat = []
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[j][i])
    return new_mat
 
# function to update the matrix
# if we move / swipe left
def move_left(grid):
 
    # first compress the grid
    new_grid, changed1 = compress(grid)
 
    # then merge the cells.
    new_grid, changed2 = merge(new_grid)
     
    changed = changed1 or changed2
 
    # again compress after merging.
    new_grid, temp = compress(new_grid)
 
    # return new matrix and bool changed
    # telling whether the grid is same
    # or different
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe right
def move_right(grid):
 
    # to move right we just reverse
    # the matrix
    new_grid = reverse(grid)
 
    # then move left
    new_grid, changed = move_left(new_grid)
 
    # then again reverse matrix will
    # give us desired result
    new_grid = reverse(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe up
def move_up(grid):
 
    # to move up we just take
    # transpose of matrix
    new_grid = transpose(grid)
 
    # then move left (calling all
    # included functions) then
    new_grid, changed = move_left(new_grid)
 
    # again take transpose will give
    # desired results
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe down
def move_down(grid):
 
    # to move down we take transpose
    new_grid = transpose(grid)
 
    # move right and then again
    new_grid, changed = move_right(new_grid)
 
    # take transpose will give desired
    # results.
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# this file only contains all the logic
# functions to be called in main function
# present in the other file


Python3
# logic.py to be
# imported in the 2048.py file
 
# importing random package
# for methods to generate random
# numbers.
import random
 
# function to initialize game / grid
# at the start
def start_game():
 
    # declaring an empty list then
    # appending 4 list each with four
    # elements as 0.
    mat =[]
    for i in range(4):
        mat.append([0] * 4)
 
    # printing controls for user
    print("Commands are as follows : ")
    print("'W' or 'w' : Move Up")
    print("'S' or 's' : Move Down")
    print("'A' or 'a' : Move Left")
    print("'D' or 'd' : Move Right")
 
    # calling the function to add
    # a new 2 in grid after every step
    add_new_2(mat)
    return mat
 
# function to add a new 2 in
# grid at any random empty cell
def add_new_2(mat):
 
   # choosing a random index for
   # row and column.
    r = random.randint(0, 3)
    c = random.randint(0, 3)
 
    # while loop will break as the
    # random cell chosen will be empty
    # (or contains zero)
    while(mat[r] != 0):
        r = random.randint(0, 3)
        c = random.randint(0, 3)
 
    # we will place a 2 at that empty
    # random cell.
    mat[r] = 2
 
# function to get the current
# state of game
def get_current_state(mat):
 
    # if any cell contains
    # 2048 we have won
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 2048):
                return 'WON'
 
    # if we are still left with
    # atleast one empty cell
    # game is not yet over
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 0):
                return 'GAME NOT OVER'
 
    # or if no cell is empty now
    # but if after any move left, right,
    # up or down, if any two cells
    # gets merged and create an empty
    # cell then also game is not yet over
    for i in range(3):
        for j in range(3):
            if(mat[i][j]== mat[i + 1][j] or mat[i][j]== mat[i][j + 1]):
                return 'GAME NOT OVER'
 
    for j in range(3):
        if(mat[3][j]== mat[3][j + 1]):
            return 'GAME NOT OVER'
 
    for i in range(3):
        if(mat[i][3]== mat[i + 1][3]):
            return 'GAME NOT OVER'
 
    # else we have lost the game
    return 'LOST'
 
# all the functions defined below
# are for left swap initially.
 
# function to compress the grid
# after every step before and
# after merging cells.
def compress(mat):
 
    # bool variable to determine
    # any change happened or not
    changed = False
 
    # empty grid
    new_mat = []
 
    # with all cells empty
    for i in range(4):
        new_mat.append([0] * 4)
         
    # here we will shift entries
    # of each cell to it's extreme
    # left row by row
    # loop to traverse rows
    for i in range(4):
        pos = 0
 
        # loop to traverse each column
        # in respective row
        for j in range(4):
            if(mat[i][j] != 0):
                 
                # if cell is non empty then
                # we will shift it's number to
                # previous empty cell in that row
                # denoted by pos variable
                new_mat[i][pos] = mat[i][j]
                 
                if(j != pos):
                    changed = True
                pos += 1
 
    # returning new compressed matrix
    # and the flag variable.
    return new_mat, changed
 
# function to merge the cells
# in matrix after compressing
def merge(mat):
     
    changed = False
     
    for i in range(4):
        for j in range(3):
 
            # if current cell has same value as
            # next cell in the row and they
            # are non empty then
            if(mat[i][j] == mat[i][j + 1] and mat[i][j] != 0):
 
                # double current cell value and
                # empty the next cell
                mat[i][j] = mat[i][j] * 2
                mat[i][j + 1] = 0
 
                # make bool variable True indicating
                # the new grid after merging is
                # different.
                changed = True
 
    return mat, changed
 
# function to reverse the matrix
# means reversing the content of
# each row (reversing the sequence)
def reverse(mat):
    new_mat =[]
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[i][3 - j])
    return new_mat
 
# function to get the transpose
# of matrix means interchanging
# rows and column
def transpose(mat):
    new_mat = []
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[j][i])
    return new_mat
 
# function to update the matrix
# if we move / swipe left
def move_left(grid):
 
    # first compress the grid
    new_grid, changed1 = compress(grid)
 
    # then merge the cells.
    new_grid, changed2 = merge(new_grid)
     
    changed = changed1 or changed2
 
    # again compress after merging.
    new_grid, temp = compress(new_grid)
 
    # return new matrix and bool changed
    # telling whether the grid is same
    # or different
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe right
def move_right(grid):
 
    # to move right we just reverse
    # the matrix
    new_grid = reverse(grid)
 
    # then move left
    new_grid, changed = move_left(new_grid)
 
    # then again reverse matrix will
    # give us desired result
    new_grid = reverse(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe up
def move_up(grid):
 
    # to move up we just take
    # transpose of matrix
    new_grid = transpose(grid)
 
    # then move left (calling all
    # included functions) then
    new_grid, changed = move_left(new_grid)
 
    # again take transpose will give
    # desired results
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe down
def move_down(grid):
 
    # to move down we take transpose
    new_grid = transpose(grid)
 
    # move right and then again
    new_grid, changed = move_right(new_grid)
 
    # take transpose will give desired
    # results.
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# this file only contains all the logic
# functions to be called in main function
# present in the other file


Python3
# 2048.py
 
# importing the logic.py file
# where we have written all the
# logic functions used.
import logic
 
# Driver code
if __name__ == '__main__':
     
# calling start_game function
# to initialize the matrix
    mat = logic.start_game()
 
while(True):
 
    # taking the user input
    # for next step
    x = input("Press the command : ")
 
    # we have to move up
    if(x == 'W' or x == 'w'):
 
        # call the move_up function
        mat, flag = logic.move_up(mat)
 
        # get the current state and print it
        status = logic.get_current_state(mat)
        print(status)
 
        # if game not ove then continue
        # and add a new two
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
 
        # else break the loop
        else:
            break
 
    # the above process will be followed
    # in case of each type of move
    # below
 
    # to move down
    elif(x == 'S' or x == 's'):
        mat, flag = logic.move_down(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
 
    # to move left
    elif(x == 'A' or x == 'a'):
        mat, flag = logic.move_left(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
 
    # to move right
    elif(x == 'D' or x == 'd'):
        mat, flag = logic.move_right(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
    else:
        print("Invalid Key Pressed")
 
    # print the matrix after each
    # move.
    print(mat)


Python3

# logic.py to be
# imported in the 2048.py file
 
# importing random package
# for methods to generate random
# numbers.
import random
 
# function to initialize game / grid
# at the start
def start_game():
 
    # declaring an empty list then
    # appending 4 list each with four
    # elements as 0.
    mat =[]
    for i in range(4):
        mat.append([0] * 4)
 
    # printing controls for user
    print("Commands are as follows : ")
    print("'W' or 'w' : Move Up")
    print("'S' or 's' : Move Down")
    print("'A' or 'a' : Move Left")
    print("'D' or 'd' : Move Right")
 
    # calling the function to add
    # a new 2 in grid after every step
    add_new_2(mat)
    return mat
 
# function to add a new 2 in
# grid at any random empty cell
def add_new_2(mat):
 
   # choosing a random index for
   # row and column.
    r = random.randint(0, 3)
    c = random.randint(0, 3)
 
    # while loop will break as the
    # random cell chosen will be empty
    # (or contains zero)
    while(mat[r] != 0):
        r = random.randint(0, 3)
        c = random.randint(0, 3)
 
    # we will place a 2 at that empty
    # random cell.
    mat[r] = 2
 
# function to get the current
# state of game
def get_current_state(mat):
 
    # if any cell contains
    # 2048 we have won
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 2048):
                return 'WON'
 
    # if we are still left with
    # atleast one empty cell
    # game is not yet over
    for i in range(4):
        for j in range(4):
            if(mat[i][j]== 0):
                return 'GAME NOT OVER'
 
    # or if no cell is empty now
    # but if after any move left, right,
    # up or down, if any two cells
    # gets merged and create an empty
    # cell then also game is not yet over
    for i in range(3):
        for j in range(3):
            if(mat[i][j]== mat[i + 1][j] or mat[i][j]== mat[i][j + 1]):
                return 'GAME NOT OVER'
 
    for j in range(3):
        if(mat[3][j]== mat[3][j + 1]):
            return 'GAME NOT OVER'
 
    for i in range(3):
        if(mat[i][3]== mat[i + 1][3]):
            return 'GAME NOT OVER'
 
    # else we have lost the game
    return 'LOST'
 
# all the functions defined below
# are for left swap initially.
 
# function to compress the grid
# after every step before and
# after merging cells.
def compress(mat):
 
    # bool variable to determine
    # any change happened or not
    changed = False
 
    # empty grid
    new_mat = []
 
    # with all cells empty
    for i in range(4):
        new_mat.append([0] * 4)
         
    # here we will shift entries
    # of each cell to it's extreme
    # left row by row
    # loop to traverse rows
    for i in range(4):
        pos = 0
 
        # loop to traverse each column
        # in respective row
        for j in range(4):
            if(mat[i][j] != 0):
                 
                # if cell is non empty then
                # we will shift it's number to
                # previous empty cell in that row
                # denoted by pos variable
                new_mat[i][pos] = mat[i][j]
                 
                if(j != pos):
                    changed = True
                pos += 1
 
    # returning new compressed matrix
    # and the flag variable.
    return new_mat, changed
 
# function to merge the cells
# in matrix after compressing
def merge(mat):
     
    changed = False
     
    for i in range(4):
        for j in range(3):
 
            # if current cell has same value as
            # next cell in the row and they
            # are non empty then
            if(mat[i][j] == mat[i][j + 1] and mat[i][j] != 0):
 
                # double current cell value and
                # empty the next cell
                mat[i][j] = mat[i][j] * 2
                mat[i][j + 1] = 0
 
                # make bool variable True indicating
                # the new grid after merging is
                # different.
                changed = True
 
    return mat, changed
 
# function to reverse the matrix
# means reversing the content of
# each row (reversing the sequence)
def reverse(mat):
    new_mat =[]
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[i][3 - j])
    return new_mat
 
# function to get the transpose
# of matrix means interchanging
# rows and column
def transpose(mat):
    new_mat = []
    for i in range(4):
        new_mat.append([])
        for j in range(4):
            new_mat[i].append(mat[j][i])
    return new_mat
 
# function to update the matrix
# if we move / swipe left
def move_left(grid):
 
    # first compress the grid
    new_grid, changed1 = compress(grid)
 
    # then merge the cells.
    new_grid, changed2 = merge(new_grid)
     
    changed = changed1 or changed2
 
    # again compress after merging.
    new_grid, temp = compress(new_grid)
 
    # return new matrix and bool changed
    # telling whether the grid is same
    # or different
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe right
def move_right(grid):
 
    # to move right we just reverse
    # the matrix
    new_grid = reverse(grid)
 
    # then move left
    new_grid, changed = move_left(new_grid)
 
    # then again reverse matrix will
    # give us desired result
    new_grid = reverse(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe up
def move_up(grid):
 
    # to move up we just take
    # transpose of matrix
    new_grid = transpose(grid)
 
    # then move left (calling all
    # included functions) then
    new_grid, changed = move_left(new_grid)
 
    # again take transpose will give
    # desired results
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# function to update the matrix
# if we move / swipe down
def move_down(grid):
 
    # to move down we take transpose
    new_grid = transpose(grid)
 
    # move right and then again
    new_grid, changed = move_right(new_grid)
 
    # take transpose will give desired
    # results.
    new_grid = transpose(new_grid)
    return new_grid, changed
 
# this file only contains all the logic
# functions to be called in main function
# present in the other file

2048.py

Python3

# 2048.py
 
# importing the logic.py file
# where we have written all the
# logic functions used.
import logic
 
# Driver code
if __name__ == '__main__':
     
# calling start_game function
# to initialize the matrix
    mat = logic.start_game()
 
while(True):
 
    # taking the user input
    # for next step
    x = input("Press the command : ")
 
    # we have to move up
    if(x == 'W' or x == 'w'):
 
        # call the move_up function
        mat, flag = logic.move_up(mat)
 
        # get the current state and print it
        status = logic.get_current_state(mat)
        print(status)
 
        # if game not ove then continue
        # and add a new two
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
 
        # else break the loop
        else:
            break
 
    # the above process will be followed
    # in case of each type of move
    # below
 
    # to move down
    elif(x == 'S' or x == 's'):
        mat, flag = logic.move_down(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
 
    # to move left
    elif(x == 'A' or x == 'a'):
        mat, flag = logic.move_left(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
 
    # to move right
    elif(x == 'D' or x == 'd'):
        mat, flag = logic.move_right(mat)
        status = logic.get_current_state(mat)
        print(status)
        if(status == 'GAME NOT OVER'):
            logic.add_new_2(mat)
        else:
            break
    else:
        print("Invalid Key Pressed")
 
    # print the matrix after each
    # move.
    print(mat)

输出 :