鱼C论坛

 找回密码
 立即注册
查看: 1505|回复: 2

[作品展示] 2048 乞丐版

[复制链接]
发表于 2021-7-12 23:25:32 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
继飞机大战之后的第二款全部由自己开发设计的小游戏,记录一下^_^
过程中遇到一些问题,很开心自己都能较好的解决 ,不过运行起来感觉有点慢XD,希望下次能写出更好的作品
# 运行速度较慢 不知道是为啥
# 空格是回到上一步
# 写入了检测是否死局的功能
# 最大的收获应该是对矩阵有了初步的了解 很高兴能用到数学书上的知识
import pygame
import random as r
import sys
import traceback
from pygame.locals import *

### py(3.9.5)
pygame.init()
screen_size = width, height = 400, 400
screen = pygame.display.set_mode(screen_size)
clock = pygame.time.Clock()
fps = 30

# 列表中是否有零
def not_zero_num(lista):
    for i in range(len(lista)):
        if lista[i] != 0:
            return lista[i], i

# 清除列表前n个0 orient = False <---, orient = True --->
def clear_zero(listb, orient = False):
    # 先清除中间部分
    target_list = listb.copy()
    for i in range(len(target_list) - 1):
        if target_list[i] == 0:
            target_list.pop(i)
            target_list.insert(len(target_list), 0)
    if not orient :
        for i in range(len(target_list)):
            if target_list[0] == 0:
                target_list.pop(0)
                target_list.append(0)
    elif orient:
        length = len(target_list)
        for i in range(length):
            if target_list[length - 1] == 0:
                target_list.pop(length - 1)
                target_list.insert(0, 0)
    return target_list

# 主函数 移动矩阵
def move_box(listc, orient = False, high_dim = False): # <--- 移动方向 orient 默认方向
    calc_list = listc[:] # 好像列表复制不好用
    calc_list = clear_zero(calc_list, orient)
    if orient:
        for i in range(len(calc_list) - 1):
            if calc_list[len(calc_list) - 1 - i] == calc_list[len(calc_list) - 2 - i]:
                calc_list[len(calc_list) - 1 - i] = 2 * calc_list[len(calc_list) - 1 - i]
                calc_list.pop(len(calc_list) - 2 - i)
                calc_list.insert(0, 0)
    elif not orient:
        for i in range(len(calc_list) - 1):
            if calc_list[i] == calc_list[i + 1]:
                calc_list[i] = calc_list[i] * 2
                calc_list.pop(i + 1)
                calc_list.insert(len(calc_list), 0)
    return calc_list

# 转置矩阵
def reverse_matrix(matrix):
    result = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
    for y in range(len(matrix)):
        for x in range(len(matrix[0])):
            result[y][x] = matrix[x][y]
    return result

# 随机空白位置生成新数字
def new_num(matrix):
    blank = []
    for y in range(len(matrix)):
        for x in range(len(matrix[0])):
            if not matrix[y][x]:
                blank.append((y, x))
    if not blank:
        return False
    else:
        select = r.choice(blank)
        matrix[select[0]][select[1]] = r.choice([2,4])
        return True

# 色库
BLACK = 0, 0, 0
GREEN = 0, 255, 0

# 字体
font = pygame.font.Font(None, 20)

# 初始化数据
main_list = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
font_list = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
font_pos =  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
check =     [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] # 检验矩阵
memorize =  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] # 记忆矩阵
running = True
row, col = 4, 4
rect_size = x, y = 96, 96
check_active = False
new_num(main_list) # 初始化游戏

def move_left(row, matrix):
    for i in range(row):
        matrix[i] = move_box(matrix[i], False)
    return matrix

def move_right(row, matrix):
    for i in range(row):
        matrix[i] = move_box(matrix[i], True)
    return matrix

def move_up(col, matrix):
    matrix = reverse_matrix(matrix)
    move_left(col, matrix)          
    matrix = reverse_matrix(matrix)
    return matrix

def move_down(col, matrix):
    matrix = reverse_matrix(matrix)
    move_right(col, matrix)
    matrix = reverse_matrix(matrix)
    return matrix

# 记录文字位置初始数据
for i in range(screen_size[0] // x): # 行
    for j in range(screen_size[1] // y): # 列
        font_pos[i][j] = (pygame.draw.rect(screen, BLACK, [i * 100 + 2, j * 100 + 2, x, y]).center)

while running:
    # 检测事件
    
    screen.fill(GREEN)
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        # 用户操作
        key_pressed = pygame.key.get_pressed()
        if key_pressed[K_LEFT] or key_pressed[K_RIGHT] or key_pressed[K_DOWN] or key_pressed[K_UP]:
            memorize = main_list[:]
            check_active = True
            if key_pressed[K_LEFT]:
                main_list = move_left(row, main_list)
            if key_pressed[K_RIGHT]:
                main_list = move_right(row, main_list)
            if key_pressed[K_DOWN]:
                main_list = move_down(col, main_list)
            if key_pressed[K_UP]:
                main_list = move_up(col, main_list)

            check = main_list[:]
            check = move_left(row, check)
            if check == main_list:
                check = move_right(row, check)
                if check == main_list:
                    check = move_down(col, check)
                    if  check == main_list:
                        move_up(col, check)
                        if  check == main_list:
                            print("game over")
                            # 检验是否真的无法移动
                            ENDDING = True
                            # game over
                            while ENDDING:
                                for event in pygame.event.get():
                                    if event.type == QUIT:
                                        pygame.quit()
                                        sys.exit()
                                    if event.type == KEYDOWN:
                                        if event.key == K_RETURN:
                                            ENDDING = False
                                            # reset
                                            main_list = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
                                            font_list = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
                                            check =  [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]
                                            new_num(main_list)
                                            running = True
                                            row, col = 4, 4
                                            rect_size = x, y = 96, 96
                                            check_active = False
                                screen.fill(BLACK)
                                font_rect = font.render("Game Over. Press [Enter] to continue", True, (255,255,255)).get_rect()
                                font_rect.center = screen_size[0] // 2, screen_size[1] // 2
                                screen.blit(font.render("Game Over. Press [Enter] to continue", True, (255,255,255)),font_rect)
                                pygame.display.flip()
            new_num(main_list)

        # 恢复上一步
        if event.type == KEYDOWN:
            if event.key == K_SPACE:
                if check_active:
                    main_list = memorize.copy()
                    check_active = False

    # 绘制背景 及 数据
    for i in range(screen_size[0] // x): # 列
        for j in range(screen_size[1] // y): # 行
            font_list[i][j] = font.render(str(main_list[j][i]), True, GREEN)
            pygame.draw.rect(screen, BLACK, [i * 100 + 2, j * 100 + 2, x, y])
            if main_list[j][i] != 0:
                screen.blit(font_list[i][j], (font_pos[i][j][0] - font_list[i][j].get_rect().width // 2,\
                                              font_pos[i][j][1] - font_list[i][j].get_rect().height // 2))

    pygame.display.flip()
    clock.tick(fps)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-7-12 23:26:36 | 显示全部楼层
呀,调试之后忘了把壳子套上了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-12 23:49:34 | 显示全部楼层
思路很棒
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 18:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表