• python快速实现2048小游戏


    《2048》是一款比较流行的数字游戏,最早于2014年3月20日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。

    操作指南:

    每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方乱数出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。不断的叠加最终拼凑出2048这个数字就算成功。

    游戏技巧:

    1. 最大数尽可能放在角落。

    2. 数字按顺序紧邻排列。

    3. 首先满足最大数和次大数在的那一列/行是满的。

    4. 时刻注意活动较大数(32以上)旁边要有相近的数。

    5. 以大数所在的一行为主要移动方向

    6. 不要急于“清理桌面”。

    完整代码如下:

    logic.py

    1. import random
    2. import constants as c
    3. def new_game(n):
    4. matrix = []
    5. for i in range(n):
    6. matrix.append([0] * n)
    7. matrix = add_two(matrix)
    8. matrix = add_two(matrix)
    9. return matrix
    10. def add_two(mat):
    11. a = random.randint(0, len(mat)-1)
    12. b = random.randint(0, len(mat)-1)
    13. while mat[a][b] != 0:
    14. a = random.randint(0, len(mat)-1)
    15. b = random.randint(0, len(mat)-1)
    16. mat[a][b] = 2
    17. return mat
    18. def game_state(mat):
    19. # check for win cell
    20. for i in range(len(mat)):
    21. for j in range(len(mat[0])):
    22. if mat[i][j] == 2048:
    23. return 'win'
    24. # check for any zero entries
    25. for i in range(len(mat)):
    26. for j in range(len(mat[0])):
    27. if mat[i][j] == 0:
    28. return 'not over'
    29. # check for same cells that touch each other
    30. for i in range(len(mat)-1):
    31. # intentionally reduced to check the row on the right and below
    32. # more elegant to use exceptions but most likely this will be their solution
    33. for j in range(len(mat[0])-1):
    34. if mat[i][j] == mat[i+1][j] or mat[i][j+1] == mat[i][j]:
    35. return 'not over'
    36. for k in range(len(mat)-1): # to check the left/right entries on the last row
    37. if mat[len(mat)-1][k] == mat[len(mat)-1][k+1]:
    38. return 'not over'
    39. for j in range(len(mat)-1): # check up/down entries on last column
    40. if mat[j][len(mat)-1] == mat[j+1][len(mat)-1]:
    41. return 'not over'
    42. return 'lose'
    43. def reverse(mat):
    44. new = []
    45. for i in range(len(mat)):
    46. new.append([])
    47. for j in range(len(mat[0])):
    48. new[i].append(mat[i][len(mat[0])-j-1])
    49. return new
    50. def transpose(mat):
    51. new = []
    52. for i in range(len(mat[0])):
    53. new.append([])
    54. for j in range(len(mat)):
    55. new[i].append(mat[j][i])
    56. return new
    57. def cover_up(mat):
    58. new = []
    59. for j in range(c.GRID_LEN):
    60. partial_new = []
    61. for i in range(c.GRID_LEN):
    62. partial_new.append(0)
    63. new.append(partial_new)
    64. done = False
    65. for i in range(c.GRID_LEN):
    66. count = 0
    67. for j in range(c.GRID_LEN):
    68. if mat[i][j] != 0:
    69. new[i][count] = mat[i][j]
    70. if j != count:
    71. done = True
    72. count += 1
    73. return new, done
    74. def merge(mat, done):
    75. for i in range(c.GRID_LEN):
    76. for j in range(c.GRID_LEN-1):
    77. if mat[i][j] == mat[i][j+1] and mat[i][j] != 0:
    78. mat[i][j] *= 2
    79. mat[i][j+1] = 0
    80. done = True
    81. return mat, done
    82. def up(game):
    83. print("up")
    84. # return matrix after shifting up
    85. game = transpose(game)
    86. game, done = cover_up(game)
    87. game, done = merge(game, done)
    88. game = cover_up(game)[0]
    89. game = transpose(game)
    90. return game, done
    91. def down(game):
    92. print("down")
    93. # return matrix after shifting down
    94. game = reverse(transpose(game))
    95. game, done = cover_up(game)
    96. game, done = merge(game, done)
    97. game = cover_up(game)[0]
    98. game = transpose(reverse(game))
    99. return game, done
    100. def left(game):
    101. print("left")
    102. # return matrix after shifting left
    103. game, done = cover_up(game)
    104. game, done = merge(game, done)
    105. game = cover_up(game)[0]
    106. return game, done
    107. def right(game):
    108. print("right")
    109. # return matrix after shifting right
    110. game = reverse(game)
    111. game, done = cover_up(game)
    112. game, done = merge(game, done)
    113. game = cover_up(game)[0]
    114. game = reverse(game)
    115. return game, done

    constants.py

    1. SIZE = 400
    2. GRID_LEN = 4
    3. GRID_PADDING = 10
    4. BACKGROUND_COLOR_GAME = "#92877d"
    5. BACKGROUND_COLOR_CELL_EMPTY = "#9e948a"
    6. BACKGROUND_COLOR_DICT = {
    7. 2: "#eee4da",
    8. 4: "#ede0c8",
    9. 8: "#f2b179",
    10. 16: "#f59563",
    11. 32: "#f67c5f",
    12. 64: "#f65e3b",
    13. 128: "#edcf72",
    14. 256: "#edcc61",
    15. 512: "#edc850",
    16. 1024: "#edc53f",
    17. 2048: "#edc22e",
    18. 4096: "#eee4da",
    19. 8192: "#edc22e",
    20. 16384: "#f2b179",
    21. 32768: "#f59563",
    22. 65536: "#f67c5f",
    23. }
    24. CELL_COLOR_DICT = {
    25. 2: "#776e65",
    26. 4: "#776e65",
    27. 8: "#f9f6f2",
    28. 16: "#f9f6f2",
    29. 32: "#f9f6f2",
    30. 64: "#f9f6f2",
    31. 128: "#f9f6f2",
    32. 256: "#f9f6f2",
    33. 512: "#f9f6f2",
    34. 1024: "#f9f6f2",
    35. 2048: "#f9f6f2",
    36. 4096: "#776e65",
    37. 8192: "#f9f6f2",
    38. 16384: "#776e65",
    39. 32768: "#776e65",
    40. 65536: "#f9f6f2",
    41. }
    42. FONT = ("Verdana",40,"bold")
    43. KEY_QUIT = "Escape"
    44. KEY_BACK = "b"
    45. KEY_UP = "Up"
    46. KEY_DOWN = "Down"
    47. KEY_LEFT = "Left"
    48. KEY_RIGHT = "Right"
    49. KEY_UP_ALT1 = "w"
    50. KEY_DOWN_ALT1 = "s"
    51. KEY_LEFT_ALT1 = "a"
    52. KEY_RIGHT_ALT1 = "d"
    53. KEY_UP_ALT2 = "i"
    54. KEY_DOWN_ALT2 = "k"
    55. KEY_LEFT_ALT2 = "j"
    56. KEY_RIGHT_ALT2 = "l"

    run.py

    1. from tkinter import Frame, Label, CENTER
    2. import random
    3. import logic
    4. import constants as c
    5. def gen():
    6. return random.randint(0, c.GRID_LEN - 1)
    7. class GameGrid(Frame):
    8. def __init__(self):
    9. Frame.__init__(self)
    10. self.grid()
    11. self.master.title('2048')
    12. self.master.bind("", self.key_down)
    13. self.commands = {
    14. c.KEY_UP: logic.up,
    15. c.KEY_DOWN: logic.down,
    16. c.KEY_LEFT: logic.left,
    17. c.KEY_RIGHT: logic.right,
    18. c.KEY_UP_ALT1: logic.up,
    19. c.KEY_DOWN_ALT1: logic.down,
    20. c.KEY_LEFT_ALT1: logic.left,
    21. c.KEY_RIGHT_ALT1: logic.right,
    22. c.KEY_UP_ALT2: logic.up,
    23. c.KEY_DOWN_ALT2: logic.down,
    24. c.KEY_LEFT_ALT2: logic.left,
    25. c.KEY_RIGHT_ALT2: logic.right,
    26. }
    27. self.grid_cells = []
    28. self.init_grid()
    29. self.matrix = logic.new_game(c.GRID_LEN)
    30. self.history_matrixs = []
    31. self.update_grid_cells()
    32. self.mainloop()
    33. def init_grid(self):
    34. background = Frame(self, bg=c.BACKGROUND_COLOR_GAME,width=c.SIZE, height=c.SIZE)
    35. background.grid()
    36. for i in range(c.GRID_LEN):
    37. grid_row = []
    38. for j in range(c.GRID_LEN):
    39. cell = Frame(
    40. background,
    41. bg=c.BACKGROUND_COLOR_CELL_EMPTY,
    42. width=c.SIZE / c.GRID_LEN,
    43. height=c.SIZE / c.GRID_LEN
    44. )
    45. cell.grid(
    46. row=i,
    47. column=j,
    48. padx=c.GRID_PADDING,
    49. pady=c.GRID_PADDING
    50. )
    51. t = Label(
    52. master=cell,
    53. text="",
    54. bg=c.BACKGROUND_COLOR_CELL_EMPTY,
    55. justify=CENTER,
    56. font=c.FONT,
    57. width=5,
    58. height=2)
    59. t.grid()
    60. grid_row.append(t)
    61. self.grid_cells.append(grid_row)
    62. def update_grid_cells(self):
    63. for i in range(c.GRID_LEN):
    64. for j in range(c.GRID_LEN):
    65. new_number = self.matrix[i][j]
    66. if new_number == 0:
    67. self.grid_cells[i][j].configure(text="",bg=c.BACKGROUND_COLOR_CELL_EMPTY)
    68. else:
    69. self.grid_cells[i][j].configure(
    70. text=str(new_number),
    71. bg=c.BACKGROUND_COLOR_DICT[new_number],
    72. fg=c.CELL_COLOR_DICT[new_number]
    73. )
    74. self.update_idletasks()
    75. def key_down(self, event):
    76. key = event.keysym
    77. print(event)
    78. if key == c.KEY_QUIT: exit()
    79. if key == c.KEY_BACK and len(self.history_matrixs) > 1:
    80. self.matrix = self.history_matrixs.pop()
    81. self.update_grid_cells()
    82. print('back on step total step:', len(self.history_matrixs))
    83. elif key in self.commands:
    84. self.matrix, done = self.commands[key](self.matrix)
    85. if done:
    86. self.matrix = logic.add_two(self.matrix)
    87. # record last move
    88. self.history_matrixs.append(self.matrix)
    89. self.update_grid_cells()
    90. if logic.game_state(self.matrix) == 'win':
    91. self.grid_cells[1][1].configure(text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
    92. self.grid_cells[1][2].configure(text="Win!", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
    93. if logic.game_state(self.matrix) == 'lose':
    94. self.grid_cells[1][1].configure(text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
    95. self.grid_cells[1][2].configure(text="Lose!", bg=c.BACKGROUND_COLOR_CELL_EMPTY)
    96. def generate_next(self):
    97. index = (gen(), gen())
    98. while self.matrix[index[0]][index[1]] != 0:
    99. index = (gen(), gen())
    100. self.matrix[index[0]][index[1]] = 2
    101. game_grid = GameGrid()

    操作方式:

    方向键:上下左右

    26键中的:WSAD

    26键中的:IKJL

    ESC键退出游戏,b键返回上一步

    为增加游戏可玩性,此游戏最大叠加数为65536

    运行结果如下所示:

    运行run.py即可开始游戏

     

     

  • 相关阅读:
    C++中类和动态内存分配
    kafka分区迁移失败任务的处理
    npm中的.package-lock.json包管理配置文件 package.json自己创建的包配置文件(npm init -y)
    推荐6个AI工具网站
    Web前端开发具有哪些特点?
    当贝投影4K激光投影X3 Pro获得一致好评:万元投影仪首选
    vscode Coder Runner 运行C++
    使用InstantOC实现动态遮挡剔除 + LOD效果
    MacOS lldb 使用记录
    HCIP--IPV6综合实验
  • 原文地址:https://blog.csdn.net/qq_38563206/article/details/128212265