You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

519 lines
15 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()