《2048》是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。
操作指南:
每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。
游戏技巧:
最大数尽可能放在角落。
数字按顺序紧邻排列。
首先满足最大数和次大数在的那一列/行是满的。
时刻注意活动较大数(32以上)旁边要有相近的数。
以大数所在的一行为主要移动方向
不要急于“清理桌面”。
完整代码如下:
logic.py
- import random
- import constants as c
-
-
-
- def new_game(n):
- matrix = []
- for i in range(n):
- matrix.append([0] * n)
- matrix = add_two(matrix)
- matrix = add_two(matrix)
- return matrix
-
-
-
- def add_two(mat):
- a = random.randint(0, len(mat)-1)
- b = random.randint(0, len(mat)-1)
- while mat[a][b] != 0:
- a = random.randint(0, len(mat)-1)
- b = random.randint(0, len(mat)-1)
- mat[a][b] = 2
- return mat
-
-
-
- def game_state(mat):
- # check for win cell
- for i in range(len(mat)):
- for j in range(len(mat[0])):
- if mat[i][j] == 2048:
- return 'win'
- # check for any zero entries
- for i in range(len(mat)):
- for j in range(len(mat[0])):
- if mat[i][j] == 0:
- return 'not over'
- # check for same cells that touch each other
- for i in range(len(mat)-1):
- # intentionally reduced to check the row on the right and below
- # more elegant to use exceptions but most likely this will be their solution
- for j in range(len(mat[0])-1):
- if mat[i][j] == mat[i+1][j] or mat[i][j+1] == mat[i][j]:
- return 'not over'
- for k in range(len(mat)-1): # to check the left/right entries on the last row
- if mat[len(mat)-1][k] == mat[len(mat)-1][k+1]:
- return 'not over'
- for j in range(len(mat)-1): # check up/down entries on last column
- if mat[j][len(mat)-1] == mat[j+1][len(mat)-1]:
- return 'not over'
- return 'lose'
-
-
-
- def reverse(mat):
- new = []
- for i in range(len(mat)):
- new.append([])
- for j in range(len(mat[0])):
- new[i].append(mat[i][len(mat[0])-j-1])
- return new
-
-
-
- def transpose(mat):
- new = []
- for i in range(len(mat[0])):
- new.append([])
- for j in range(len(mat)):
- new[i].append(mat[j][i])
- return new
-
-
-
- def cover_up(mat):
- new = []
- for j in range(c.GRID_LEN):
- partial_new = []
- for i in range(c.GRID_LEN):
- partial_new.append(0)
- new.append(partial_new)
- done = False
- for i in range(c.GRID_LEN):
- count = 0
- for j in range(c.GRID_LEN):
- if mat[i][j] != 0:
- new[i][count] = mat[i][j]
- if j != count:
- done = True
- count += 1
- return new, done
-
- def merge(mat, done):
- for i in range(c.GRID_LEN):
- for j in range(c.GRID_LEN-1):
- if mat[i][j] == mat[i][j+1] and mat[i][j] != 0:
- mat[i][j] *= 2
- mat[i][j+1] = 0
- done = True
- return mat, done
-
- def up(game):
- print("up")
- # return matrix after shifting up
- game = transpose(game)
- game, done = cover_up(game)
- game, done = merge(game, done)
- game = cover_up(game)[0]
- game = transpose(game)
- return game, done
-
- def down(game):
- print("down")
- # return matrix after shifting down
- game = reverse(transpose(game))
- game, done = cover_up(game)
- game, done = merge(game, done)
- game = cover_up(game)[0]
- game = transpose(reverse(game))
- return game, done
-
- def left(game):
- print("left")
- # return matrix after shifting left
- game, done = cover_up(game)
- game, done = merge(game, done)
- game = cover_up(game)[0]
- return game, done
-
- def right(game):
- print("right")
- # return matrix after shifting right
- game = reverse(game)
- game, done = cover_up(game)
- game, done = merge(game, done)
- game = cover_up(game)[0]
- game = reverse(game)
- return game, done
constants.py
- SIZE = 400
- GRID_LEN = 4
- GRID_PADDING = 10
-
- BACKGROUND_COLOR_GAME = "#92877d"
- BACKGROUND_COLOR_CELL_EMPTY = "#9e948a"
-
- BACKGROUND_COLOR_DICT = {
- 2: "#eee4da",
- 4: "#ede0c8",
- 8: "#f2b179",
- 16: "#f59563",
- 32: "#f67c5f",
- 64: "#f65e3b",
- 128: "#edcf72",
- 256: "#edcc61",
- 512: "#edc850",
- 1024: "#edc53f",
- 2048: "#edc22e",
- 4096: "#eee4da",
- 8192: "#edc22e",
- 16384: "#f2b179",
- 32768: "#f59563",
- 65536: "#f67c5f",
- }
-
- CELL_COLOR_DICT = {
- 2: "#776e65",
- 4: "#776e65",
- 8: "#f9f6f2",
- 16: "#f9f6f2",
- 32: "#f9f6f2",
- 64: "#f9f6f2",
- 128: "#f9f6f2",
- 256: "#f9f6f2",
- 512: "#f9f6f2",
- 1024: "#f9f6f2",
- 2048: "#f9f6f2",
- 4096: "#776e65",
- 8192: "#f9f6f2",
- 16384: "#776e65",
- 32768: "#776e65",
- 65536: "#f9f6f2",
- }
-
- FONT = ("Verdana",40,"bold")
-
- KEY_QUIT = "Escape"
- KEY_BACK = "b"
-
- KEY_UP = "Up"
- KEY_DOWN = "Down"
- KEY_LEFT = "Left"
- KEY_RIGHT = "Right"
-
- KEY_UP_ALT1 = "w"
- KEY_DOWN_ALT1 = "s"
- KEY_LEFT_ALT1 = "a"
- KEY_RIGHT_ALT1 = "d"
-
- KEY_UP_ALT2 = "i"
- KEY_DOWN_ALT2 = "k"
- KEY_LEFT_ALT2 = "j"
- KEY_RIGHT_ALT2 = "l"
run.py
- from tkinter import Frame, Label, CENTER
- import random
- import logic
- import constants as c
-
- def gen():
- return random.randint(0, c.GRID_LEN - 1)
-
- class GameGrid(Frame):
- def __init__(self):
- Frame.__init__(self)
-
- self.grid()
- self.master.title('2048')
- self.master.bind("
" , self.key_down) -
- self.commands = {
- c.KEY_UP: logic.up,
- c.KEY_DOWN: logic.down,
- c.KEY_LEFT: logic.left,
- c.KEY_RIGHT: logic.right,
- c.KEY_UP_ALT1: logic.up,
- c.KEY_DOWN_ALT1: logic.down,
- c.KEY_LEFT_ALT1: logic.left,
- c.KEY_RIGHT_ALT1: logic.right,
- c.KEY_UP_ALT2: logic.up,
- c.KEY_DOWN_ALT2: logic.down,
- c.KEY_LEFT_ALT2: logic.left,
- c.KEY_RIGHT_ALT2: logic.right,
- }
-
- self.grid_cells = []
- self.init_grid()
- self.matrix = logic.new_game(c.GRID_LEN)
- self.history_matrixs = []
- self.update_grid_cells()
-
- self.mainloop()
-
- def init_grid(self):
- background = Frame(self, bg=c.BACKGROUND_COLOR_GAME,width=c.SIZE, height=c.SIZE)
- background.grid()
-
- for i in range(c.GRID_LEN):
- grid_row = []
- for j in range(c.GRID_LEN):
- cell = Frame(
- background,
- bg=c.BACKGROUND_COLOR_CELL_EMPTY,
- width=c.SIZE / c.GRID_LEN,
- height=c.SIZE / c.GRID_LEN
- )
- cell.grid(
- row=i,
- column=j,
- padx=c.GRID_PADDING,
- pady=c.GRID_PADDING
- )
- t = Label(
- master=cell,
- text="",
- bg=c.BACKGROUND_COLOR_CELL_EMPTY,
- justify=CENTER,
- font=c.FONT,
- width=5,
- height=2)
- t.grid()
- grid_row.append(t)
- self.grid_cells.append(grid_row)
-
- def update_grid_cells(self):
- for i in range(c.GRID_LEN):
- for j in range(c.GRID_LEN):
- new_number = self.matrix[i][j]
- if new_number == 0:
- self.grid_cells[i][j].configure(text="",bg=c.BACKGROUND_COLOR_CELL_EMPTY)
- else:
- self.grid_cells[i][j].configure(
- text=str(new_number),
- bg=c.BACKGROUND_COLOR_DICT[new_number],
- fg=c.CELL_COLOR_DICT[new_number]
- )
- self.update_idletasks()
-
- def key_down(self, event):
- key = event.keysym
- print(event)
- if key == c.KEY_QUIT: exit()
- if key == c.KEY_BACK and len(self.history_matrixs) > 1:
- self.matrix = self.history_matrixs.pop()
- self.update_grid_cells()
- print('back on step total step:', len(self.history_matrixs))
- elif key in self.commands:
- self.matrix, done = self.commands[key](self.matrix)
- if done:
- self.matrix = logic.add_two(self.matrix)
- # record last move
- self.history_matrixs.append(self.matrix)
- self.update_grid_cells()
- if logic.game_state(self.matrix) == 'win':
- self.grid_cells[1][1].configure(text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
- self.grid_cells[1][2].configure(text="Win!", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
- if logic.game_state(self.matrix) == 'lose':
- self.grid_cells[1][1].configure(text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
- self.grid_cells[1][2].configure(text="Lose!", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
-
- def generate_next(self):
- index = (gen(), gen())
- while self.matrix[index[0]][index[1]] != 0:
- index = (gen(), gen())
- self.matrix[index[0]][index[1]] = 2
-
- game_grid = GameGrid()
操作方式:
方向键:上下左右
26键中的:WSAD
26键中的:IKJL
ESC键退出游戏,b键返回上一步
为增加游戏可玩性,此游戏最大叠加数为65536
运行结果如下所示:
运行run.py即可开始游戏