import copy import pygame import random from map_config import * from button_event import * import sound ai_delay_time = 500 sound_flag = 0 #是否决定播放成功或者失败的音乐的标志位 #游戏得分 game_point = 0 game_step = 0 isAdd = 0 #板的二维数组 board = [ [0,2,4,8], [0,16,32,64], [128,0,256,0], [512,1024,0,2048] ] #返还row行 col列 #board[a,b] 对应的是a行b列 #比如说 #board = [[0,2,4,8], # [0,16,32,64], # [128,0,256,0], # [512,1024,0,2048]] # board[0][1] = 2 #板的栈 用于记录过去的值 board_stack = [] #得分的栈 用于记录过去的得分 point_stack = [] #步数的栈 用于记录过去的行动 0空 1上 2下 3左 4右 step_stack = [] #(之前弄过一个MyStack 因为有BUG只能放弃了) #获取得分 def get_point(): return game_point #获取步数 def get_step(): return game_step #获取任意行列的方块的值 def get_block_num(row,col): return board[row][col] #清除地图 def clear_map(): for row in range(0,4): for col in range(0,4): board[row][col] = 0 #判断里面有没有空的格子 def isEmpty(): for row in range(0,4): for col in range(0,4): if(board[row][col] == 0): return True return False #给数组添加新的块 #有四分之一的可能产生4 #四分之三的可能产生2 def create_new_block(): rows = random.randint(0,3) cols = random.randint(0,3)#生成行和列 while(board[rows][cols]!=0): rows = random.randint(0,3) cols = random.randint(0,3)#如果这个位置不是空的,就继续生成行和列 #print(rows,cols,board[rows][cols]) value = random.randint(0,3) if(value == 3): board[rows][cols] = 4 else: board[rows][cols] = 2 #向上移动 def move_up(): global game_point global game_step global isAdd isAdd = 0 for col in range(0,4): index = 0 for row in range(1,4): if board[row][col] > 0: #当前数字等于上边数字 #上边数字 = 上边数字 + 当前数字, 当前数字 = 0 if board[row][col] == board[index][col]: board[index][col] = board[row][col] + board[index][col] game_point += board[row][col] board[row][col] = 0 isAdd = 1 index += 1 #当前数字不等于上边数字 elif board[index][col] == 0:#当前数字上边有0 #上边数字 = 当前数字, 当前数字 = 0 board[index][col] = board[row][col] board[row][col] = 0 isAdd = 1 else: index += 1 #去除漏网之鱼 #index相当于慢指针,j相当于快指针 #也就是说快指针和慢指针中间可能存在一个以上的空格,或者index和j并未相邻 #上边数字 = 0 #数值: 上边数字 = 当前数字, 当前数字 = 0 if board[index][col] == 0: board[index][col] = board[row][col] board[row][col] = 0 isAdd = 1 game_step += isAdd return isAdd #向下移动 def move_down(): global game_point global game_step global isAdd isAdd = 0 for col in range(0,4): index = 3 for row in range(2,-1,-1): if board[row][col] > 0: #当前数字等于下边数字 #下边数字 = 下边数字 + 当前数字, 当前数字 = 0 if board[row][col] == board[index][col]: board[index][col] = board[row][col] + board[index][col] game_point += board[row][col] board[row][col] = 0 index -= 1 isAdd = 1 #当前数字不等于下边数字 elif board[index][col] == 0:#当前数字上边有0 #下边数字 = 当前数字, 当前数字 = 0 board[index][col] = board[row][col] board[row][col] = 0 isAdd = 1 else: index -= 1 #去除漏网之鱼 #index相当于慢指针,j相当于快指针 #也就是说快指针和慢指针中间可能存在一个以上的空格,或者index和j并未相邻 #下边数字 = 0 #数值: 下边数字 = 当前数字, 当前数字 = 0 if board[index][col] == 0: board[index][col] = board[row][col] board[row][col] = 0 isAdd = 1 game_step += isAdd return isAdd #向左移动 def move_left(): global game_point global game_step global isAdd isAdd = 0 for row in range(0,4): index = 0 for col in range(1,4): if board[row][col] > 0: #当前数字等于下边数字 #下边数字 = 下边数字 + 当前数字, 当前数字 = 0 if board[row][col] == board[row][index]: board[row][index] = board[row][col] + board[row][index] game_point += board[row][col] board[row][col] = 0 index += 1 isAdd = 1 #当前数字不等于下边数字 elif board[row][index] == 0:#当前数字上边有0 #下边数字 = 当前数字, 当前数字 = 0 board[row][index] = board[row][col] board[row][col] = 0 isAdd = 1 else: index += 1 #去除漏网之鱼 #index相当于慢指针,j相当于快指针 #也就是说快指针和慢指针中间可能存在一个以上的空格,或者index和j并未相邻 #下边数字 = 0 #数值: 下边数字 = 当前数字, 当前数字 = 0 if board[row][index] == 0: board[row][index] = board[row][col] board[row][col] = 0 isAdd = 1 game_step += isAdd return isAdd #向右移动 def move_right(): global game_point global game_step global isAdd isAdd = 0 for row in range(0,4): index = 3 for col in range(2,-1,-1): if board[row][col] > 0: #当前数字等于下边数字 #下边数字 = 下边数字 + 当前数字, 当前数字 = 0 if board[row][col] == board[row][index]: board[row][index] = board[row][col] + board[row][index] game_point += board[row][col] board[row][col] = 0 index -= 1 isAdd = 1 #当前数字不等于下边数字 elif board[row][index] == 0:#当前数字上边有0 #下边数字 = 当前数字, 当前数字 = 0 board[row][index] = board[row][col] board[row][col] = 0 isAdd = 1 else: index -= 1 #去除漏网之鱼 #index相当于慢指针,j相当于快指针 #也就是说快指针和慢指针中间可能存在一个以上的空格,或者index和j并未相邻 #下边数字 = 0 #数值: 下边数字 = 当前数字, 当前数字 = 0 if board[row][index] == 0: board[row][index] = board[row][col] board[row][col] = 0 isAdd = 1 game_step += isAdd return isAdd #向上移动完全操作 def go_move_up(): global board_stack global point_stack global step_stack global board board2 = copy.deepcopy(board) if move_up() == 1: #往上移 只有当移动成功了 才创建新的方块 并且把当前的情况入栈 create_new_block() #入栈 board_stack.append(board2) point_stack.append(get_point()) step_stack.append(1) #产生声音 sound.slide_sound() #向下移动完全操作 def go_move_down(): global board_stack global point_stack global step_stack global board board2 = copy.deepcopy(board) if move_down() == 1: #往下移 只有当移动成功了 才创建新的方块 并且把当前的情况入栈 create_new_block() #入栈 board_stack.append(board2) point_stack.append(get_point()) step_stack.append(2) #产生声音 sound.slide_sound() #向左移动完全操作 def go_move_left(): global board_stack global point_stack global step_stack global board board2 = copy.deepcopy(board) if move_left() == 1: #往左移 只有当移动成功了 才创建新的方块 并且把当前的情况入栈 create_new_block() #入栈 board_stack.append(board2) point_stack.append(get_point()) step_stack.append(3) #产生声音 sound.slide_sound() #向右移动完全操作 def go_move_right(): global board_stack global point_stack global step_stack global board board2 = copy.deepcopy(board) if move_right() == 1: #往右移 只有当移动成功了 才创建新的方块 并且把当前的情况入栈 create_new_block() #入栈 board_stack.append(board2) point_stack.append(get_point()) step_stack.append(4) #产生声音 sound.slide_sound() #开始基础游戏(后面可能还会添加别的功能) def start_base_game(): #定义全局变量 global game_step global game_point global isAdd global board_stack global point_stack global step_stack global board board2 = copy.deepcopy(board) #清空地图 + 创建两个格子 clear_map() create_new_block() create_new_block() #初始化变量 game_step = 0 game_point = 0 isAdd = 0 ##清空所有的栈 board_stack = [] point_stack = [] step_stack = [] ##往栈中添加当前的元素 board_stack.append(board2) point_stack.append(get_point()) step_stack.append(0) #声音的处理 sound.stop_sound() sound.background_sound() ball_x = 0 ball_y = 0 move_enable = 0 #基础游戏进行时 def base_game_going(): global ball_x,ball_y,move_enable global ai_delay_time global sound_flag #游戏正常 if judge_gameover() == False and judge_gamewin() == False: sound_flag = 0 for event in pygame.event.get(): #按钮事件检测 buttonBase.check_event(event) buttonReturn.check_event(event) buttonAI.check_event(event) buttonTips.check_event(event) buttonReshow.check_event(event) #键盘事件 基本键盘操作 if event.type == pygame.KEYDOWN: if(event.key == pygame.K_LEFT or event.key == pygame.K_a): go_move_left() if(event.key == pygame.K_RIGHT or event.key == pygame.K_d): go_move_right() if(event.key == pygame.K_UP or event.key == pygame.K_w): go_move_up() if(event.key == pygame.K_DOWN or event.key == pygame.K_s): go_move_down() if(event.key == pygame.K_z):#Z键加快速度 if ai_delay_time > 50: ai_delay_time = ai_delay_time - 50 if(event.key == pygame.K_x):#X键减慢速度 if ai_delay_time < 1000: ai_delay_time = ai_delay_time + 50 #鼠标事件 滑动鼠标手势 elif event.type == pygame.MOUSEBUTTONDOWN: ball_x,ball_y = pygame.mouse.get_pos() if ball_x > start_x and ball_x < start_x + box_size*4: #限制鼠标手势范围 if ball_y > top_of_screen and ball_y < top_of_screen + box_size*4: move_enable = 1 #print(ball_x,ball_y) elif event.type == pygame.MOUSEBUTTONUP: if move_enable == 1: move_enable = 0 ball_x_2, ball_y_2 =pygame.mouse.get_pos() dX = ball_x_2 - ball_x dY = ball_y_2 - ball_y if abs(dX) > abs(dY): if dX < 0: go_move_left() else: go_move_right() elif abs(dX) < abs(dY): if dY < 0: go_move_up() elif dY > 0: go_move_down() #游戏失败 elif judge_gameover() == True: if sound_flag == 0: sound_flag = 1 sound.stop_sound() sound.fail_sound() for event in pygame.event.get(): #按钮事件检测 buttonBase.check_event(event) buttonReturn.check_event(event) buttonAI.check_event(event) buttonTips.check_event(event) buttonReshow.check_event(event) #游戏成功 elif judge_gamewin() == True: if sound_flag == 0: sound_flag = 1 sound.stop_sound() sound.win_sound() for event in pygame.event.get(): #按钮事件检测 buttonBase.check_event(event) buttonReturn.check_event(event) buttonAI.check_event(event) buttonTips.check_event(event) buttonReshow.check_event(event) #获取空白方格 def get_empty(): lst = [] for row in range(4): for col in range(4): if board[row][col] == 0: lst.append([row, col]) return lst #判断游戏是否结束 def judge_gameover(): #当空白空格不为空时,即游戏未结束 if isEmpty() == True: return False #当空白方格为空时,判断是否存在可合并的方格 for row in range(4): for col in range(3): if board[row][col] == board[row][col + 1]: return False for row in range(3): for col in range(4): if board[row][col] == board[row + 1][col]: return False #若不满足以上两种情况,则游戏结束 return True #判断游戏是否成功 def judge_gamewin(): #检查是否有2048 maxnum = 0 for row in range(0,4): for col in range(0,4): if(board[row][col] > maxnum): maxnum = board[row][col] if maxnum == 2048: return True return False #撤回功能回调函数(用于给按键事件使用) def return_callback(): #定义全局变量 global game_step global game_point global isAdd global board_stack global point_stack global step_stack global board sound.stop_sound() sound.background_sound() if game_step != 0: board = board_stack[-1] del board_stack[-1] game_point = point_stack[-1] del point_stack[-1] del step_stack[-1] game_step -= 1 sound.return_sound()