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

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