编辑
2024-10-01
Python
00
请注意,本文编写于 264 天前,最后修改于 264 天前,其中某些信息可能已经过时。

目录

一、需求分析
二、数据模型
三、游戏逻辑
四、界面控制
五、主程序入口

一、需求分析

实现: 1. 2048核心算法   bll.py--> GameCoreController 类中. 变量: 合并时使用的一维列表 移动时使用的二维列表 方法: 零元素移至末尾() 合并() 上移动() 下移动() ..... 温馨提示:注意命名(私有化) 2. 在GameCoreController类中,定义产生随机数功能. 需求:在空白的位置上 可能是2(90%),也可能是4(10%). 1 - 10 --> 随机数 是1的概率是10% 1 --100 --> 1 <=随机数<=38 的概率是38% 3. 在GameCoreController类中,定义判断游戏是否结束的方法. 是否具有空位置 横向竖向没有相同的元素

二、数据模型

python
class DirectionModel: """ 方向数据模型 枚举 常量(命名全部大写) """ # 在整数基础上,添加一个易识别的"标签" UP = 0 DOWN = 1 LEFT = 2 RIGHT = 3 class Location: """ 位置模型 """ def __init__(self,r,c): self.r_index = r self.c_index = c

三、游戏逻辑

python
""" 游戏逻辑控制器,负责处理游戏核心算法. """ from model import DirectionModel from model import Location import random class GameCoreController: def __init__(self): self.__list_merge = None self.__map = [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], ] self.__list_empty_location = [] @property #通过计算返回的类属性,装饰器 def map(self): return self.__map def __zero_to_end(self): """ 零元素移动到末尾. """ for i in range(-1, -len(self.__list_merge) - 1, -1): if self.__list_merge[i] == 0: del self.__list_merge[i] self.__list_merge.append(0) def __merge(self): """ 合并 """ self.__zero_to_end() for i in range(len(self.__list_merge) - 1): if self.__list_merge[i] == self.__list_merge[i + 1]: self.__list_merge[i] += self.__list_merge[i + 1] del self.__list_merge[i + 1] self.__list_merge.append(0) def __move_left(self): """ 向左移动 """ for line in self.__map: self.__list_merge = line self.__merge() def __move_right(self): """ 向右移动 """ for line in self.__map: self.__list_merge = line[::-1] self.__merge() line[::-1] = self.__list_merge def __move_up(self): self.__square_matrix_transpose() self.__move_left() self.__square_matrix_transpose() def __move_down(self): self.__square_matrix_transpose() self.__move_right() self.__square_matrix_transpose() def __square_matrix_transpose(self): """ 方阵转置 :param sqr_matrix: 二维列表类型的方阵 """ for c in range(1, len(self.__map)): for r in range(c, len(self.__map)): self.__map[r][c - 1], self.__map[c - 1][r] = self.__map[c - 1][r], self.__map[r][c - 1] def move(self, dir): """ 移动 :param dir: 方向,DirectionModel类型 :return: """ if dir == DirectionModel.UP: self.__move_up() elif dir == DirectionModel.DOWN: self.__move_down() elif dir == DirectionModel.LEFT: self.__move_left() elif dir == DirectionModel.RIGHT: self.__move_right() # def generate_new_number(self): # # 思路:选出所有的空白位置(行/列),再随机挑选一个. # list_empty_location = [] # # for r in range(len(self.__map)):#0 1 2 3 # for c in range(len(self.__map[r])): # if self.__map[r][c] == 0: # # 记录r c --> 元组 # list_empty_location.append((r,c)) #   # 确定哪个空白位置1 0 # loc = random.choice(list_empty_location) #    # 产生随机数 #   if random.randint(1,10) == 1: # self.__map[loc[0]][loc[1]] = 4 # else: # self.__map[loc[0]][loc[1]] = 2 def generate_new_number(self): """ 生成新数字 """ self.__get_empty_location() if len(self.__list_empty_location) == 0: return loc = random.choice(self.__list_empty_location) # if random.randint(1, 10) == 1: # self.__map[loc.r_index][loc.c_index] = 4 # else: # self.__map[loc.r_index][loc.c_index] = 2 self.__map[loc.r_index][loc.c_index] = self.__select_random_number() # 因为在该位置生成了新数字,所以该位置就不是空位置了. self.__list_empty_location.remove(loc) def __select_random_number(self): return 4 if random.randint(1, 10) == 1 else 2 def __get_empty_location(self): # 每次统计空位置,都先清空之前的数据,避免影响本次数据. self.__list_empty_location.clear() for r in range(len(self.__map)): for c in range(len(self.__map[r])): if self.__map[r][c] == 0: self.__list_empty_location.append(Location(r, c)) def is_game_over(self): """ 游戏是否结束 :return: False表示没有结束 True 表示结束 """ # 是否具有空位置 if len(self.__list_empty_location) > 0: return False # # 判断横向有没有相同的元素 # for r in range(len(self.__map)): # for c in range(len(self.__map[r]) - 1): # 0 1 2 # if self.__map[r][c] == self.__map[r][c + 1]: # return False # # # 判断竖向有没有相同的元素 # for c in range(4): # for r in range(3): # if self.__map[r][c] == self.__map[r + 1][c]: # return False for r in range(len(self.__map)):#0 for c in range(len(self.__map[r]) - 1): # 0 1 2 if self.__map[r][c] == self.__map[r][c + 1] or self.__map[c][r] == self.__map[c+1][r]: return False return True # ---------测试代码--------------- if __name__ == "__main__": controller = GameCoreController() # controller.move_left() # print(controller.map) # controller.move_down() # print(controller.map) # controller.move(DirectionModel.LEFT) # print(controller.map) # controller.move(DirectionModel.RIGHT) # print(controller.map) controller.generate_new_number() controller.generate_new_number() controller.generate_new_number() controller.generate_new_number() controller.is_game_over() print(controller.map)

四、界面控制

python
""" 2048控制台界面 """ from bll import GameCoreController from model import DirectionModel import os class GameConsoleView: def __init__(self): self.__controller = GameCoreController() def main(self): self.__start() self.__update() def __start(self): # 产生两个数字 self.__controller.generate_new_number() self.__controller.generate_new_number() # 绘制界面 self.__draw_map() def __draw_map(self): # 清空控制台 os.system("clear") for line in self.__controller.map: for item in line: print(item,end = " ") print() def __update(self): # 循环 while True: # 判断玩家的输入 --> 移动地图 self.__move_map_for_input() # 产生新数字 self.__controller.generate_new_number() # 绘制界面 self.__draw_map() # 游戏结束判断 --> 提示 if self.__controller.is_game_over(): print("游戏结束") break def __move_map_for_input(self): dir = input("请输入方向(wsas)") dict_dir = { "w":DirectionModel.UP, "s":DirectionModel.DOWN, "a":DirectionModel.LEFT, "d":DirectionModel.RIGHT, } if dir in dict_dir: self.__controller.move(dict_dir[dir]) # ----------- if __name__ =="__main__": view = GameConsoleView() view.main()

五、主程序入口

python
""" 游戏入口 """ from ui import GameConsoleView if __name__ =="__main__": view = GameConsoleView() view.main()
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:赵耀伟

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!