使用DeepSeek定制Python小游戏——以“俄罗斯方块”为例

前言

本来想再发几个小游戏后在整理一下流程的,但是今天试了一下这个俄罗斯方块的游戏结果发现本来修改的好好的的,结果后面越改越乱,前面的版本也没保存,根据AI修改他是在几个版本改来改去,想着要求还是不能这么高。我是采用DeepSeek+Pycharm+Lingma来操作的。

贪吃蛇(含Python源码)-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/147660127?spm=1001.2014.3001.5501

外星人入侵(python)_外星人入侵python源代码-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/135963588?spm=1001.2014.3001.5501

DeepSeek部分

对于DeepSeek我是直接询问“Python可以设计哪些简单的小游戏”,然后根据推荐的游戏挑选直接感兴趣的,比如可以询问“用Python代码实现俄罗斯方块小游戏”,于是就生成了以下的代码,因为我是选择了联网搜索,所以肯定会借鉴其他博主代码:

import pygame
import random# 初始化 Pygame
pygame.init()# 游戏窗口尺寸和颜色
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
COLORS = [(0, 255, 255),    # I 型(青色)(255, 165, 0),     # L 型(橙色)(0, 0, 255),      # J 型(蓝色)(255, 255, 0),    # O 型(黄色)(0, 255, 0),       # S 型(绿色)(255, 0, 255),     # T 型(紫色)(255, 0, 0)        # Z 型(红色)
]# 方块形状定义(4x4 矩阵)
SHAPES = [[[1, 1, 1, 1]],                   # I 型[[1, 0, 0], [1, 1, 1]],           # L 型[[0, 0, 1], [1, 1, 1]],           # J 型[[1, 1], [1, 1]],                 # O 型[[0, 1, 1], [1, 1, 0]],           # S 型[[0, 1, 0], [1, 1, 1]],           # T 型[[1, 1, 0], [0, 1, 1]]            # Z 型
]# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")# 游戏区域矩阵(0表示空)
game_area = [[0] * GRID_WIDTH for _ in range(GRID_HEIGHT)]# 当前方块和位置
current_shape = None
current_pos = [0, 0]
current_color = None
score = 0def new_shape():"""生成新方块"""global current_shape, current_pos, current_colorcurrent_shape = random.choice(SHAPES)current_color = random.choice(COLORS)current_pos = [GRID_WIDTH // 2 - len(current_shape[0]) // 2, 0]def check_collision(shape, pos):"""检查方块是否与边界或已有方块碰撞"""for y, row in enumerate(shape):for x, cell in enumerate(row):if cell:px = pos[0] + xpy = pos[1] + yif px < 0 or px >= GRID_WIDTH or py >= GRID_HEIGHT:return Trueif py >= 0 and game_area[py][px]:return Truereturn Falsedef merge_shape():"""将当前方块合并到游戏区域"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:game_area[current_pos[1] + y][current_pos[0] + x] = current_colordef clear_lines():"""消除满行并更新分数"""global scorelines_to_clear = [i for i, row in enumerate(game_area) if all(cell != 0 for cell in row)]for i in lines_to_clear:del game_area[i]game_area.insert(0, [0] * GRID_WIDTH)score += len(lines_to_clear) * 100def rotate_shape():"""旋转当前方块(顺时针)"""global current_shaperotated = list(zip(*current_shape[::-1]))if not check_collision(rotated, current_pos):current_shape = rotateddef draw_grid():"""绘制游戏区域"""for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = game_area[y][x]if color:pygame.draw.rect(screen, color, (x*GRID_SIZE, y*GRID_SIZE, GRID_SIZE-1, GRID_SIZE-1))def draw_current_shape():"""绘制当前下落的方块"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:px = (current_pos[0] + x) * GRID_SIZEpy = (current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, current_color, (px, py, GRID_SIZE-1, GRID_SIZE-1))def game_loop():clock = pygame.time.Clock()fall_time = 0fall_speed = 500  # 下落间隔(毫秒)new_shape()running = Truewhile running:screen.fill(BLACK)current_time = pygame.time.get_ticks()# 处理输入事件for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:current_pos[0] -= 1if check_collision(current_shape, current_pos):current_pos[0] += 1if event.key == pygame.K_RIGHT:current_pos[0] += 1if check_collision(current_shape, current_pos):current_pos[0] -= 1if event.key == pygame.K_DOWN:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1if event.key == pygame.K_UP:rotate_shape()if event.key == pygame.K_SPACE:  # 快速下落while not check_collision(current_shape, current_pos):current_pos[1] += 1current_pos[1] -= 1# 自动下落if current_time - fall_time > fall_speed:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1merge_shape()clear_lines()new_shape()if check_collision(current_shape, current_pos):running = False  # 游戏结束fall_time = current_time# 绘制界面draw_grid()draw_current_shape()pygame.display.update()clock.tick(60)# 游戏结束提示font = pygame.font.Font(None, 74)text = font.render(f'Game Over! Score: {score}', True, WHITE)screen.blit(text, (WINDOW_WIDTH//2 - 200, WINDOW_HEIGHT//2 - 50))pygame.display.update()pygame.time.wait(3000)if __name__ == "__main__":game_loop()pygame.quit()

如果直接运行当然会存在一些的问题,比如这个右侧是空白的,但是方块无法移动过去。 

 Pycharm+Lingma部分

我主要是用的这个插件进行修改代码,一方面可以让他对代码进行优化,另一方面还能询问可以增加什么特色的功能。

比如我想增加历史最高分的模块以及右侧可以用来显示下一个方块的相关信息,本来一切都向着好方向修改,结果却越改越乱,下面的代码用DeepSeek应该是修改不了,所以建议新增功能还是一个个功能的增加测试,不然不清楚哪里有问题,还需要慢慢调试,对于要修改的地方可以通过Ctrl+F来搜索进行快速定位,对于代码报错或者警告的信息也可以询问Lingma进行修改,甚至可以进行直接替换(但是感觉不保险,怕乱改)

以下的代码存在着很多问题,但是又不想删除(毕竟改了一下午),所以也放出来的,有感兴趣的大佬可以看一下,目前存在的问题是游戏无法结束,他触碰到上底后会在下底增加方块,还有这个生存模式根据DeepSeek的操作应该是要增加障碍,还有这个不同颜色方块的功能,应该就是突然增加太多了导致代码出问题了。

# -*- coding: utf-8 -*-
import pygame
import random
import os
from typing import List, Tuple, Optional# 初始化 Pygame
pygame.init()
os.environ['PYGAME_FREETYPE'] = '1'  # 启用更好字体渲染# 新增最高分文件路径
HIGHSCORE_FILE = "tetris_highscore.txt"# 在文件开头添加字体常量
FONT_CONFIG = {"simhei": {"path": "simhei.ttf","sizes": {"title": 36, "subtitle": 28, "normal": 24}},"backup": {"name": "arial","sizes": {"title": 36, "subtitle": 28, "normal": 24}}
}# 修改字体加载函数
def load_font(font_type: str, size_type: str):"""统一字体加载函数(优化版)"""# 直接使用系统字体名称try:return pygame.font.SysFont("simhei", FONT_CONFIG["simhei"]["sizes"][size_type])except Exception as e:print(f"系统字体加载失败: {e}")try:return pygame.font.Font(None, FONT_CONFIG["backup"]["sizes"][size_type])except:return pygame.font.SysFont(FONT_CONFIG["backup"]["name"],FONT_CONFIG["backup"]["sizes"][size_type])def load_highscore():"""加载历史最高分"""try:if os.path.exists(HIGHSCORE_FILE):with open(HIGHSCORE_FILE, 'r') as f:return int(f.read().strip() or 0)return 0except Exception as e:print(f"读取最高分失败: {e}")return 0def save_highscore(score):"""保存最高分"""with open(HIGHSCORE_FILE, 'w') as f:f.write(str(score))# 游戏窗口尺寸和颜色
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40)  # 游戏区域背景色
COLORS = [(0, 255, 255),  # I 型(青色)(255, 165, 0),  # L 型(橙色)(0, 0, 255),  # J 型(蓝色)(255, 255, 0),  # O 型(黄色)(0, 255, 0),  # S 型(绿色)(255, 0, 255),  # T 型(紫色)(255, 0, 0)  # Z 型(红色)
]
# 特殊方块颜色
SPECIAL_COLORS = [(255, 100, 100),  # 爆炸红:消除整行(100, 255, 100),  # 加速绿:下落速度x2(100, 100, 255)  # 护盾蓝:免疫下一次碰撞
]
COLORS += SPECIAL_COLORS# 方块形状定义(4x4 矩阵)
SHAPES = [[[1, 1, 1, 1]],  # I 型[[1, 0, 0], [1, 1, 1]],  # L 型[[0, 0, 1], [1, 1, 1]],  # J 型[[1, 1], [1, 1]],  # O 型[[0, 1, 1], [1, 1, 0]],  # S 型[[0, 1, 0], [1, 1, 1]],  # T 型[[1, 1, 0], [0, 1, 1]]  # Z 型
]
# 新增游戏状态常量
GAME_STATES = {'START': 0,'MODE_SELECT': 1,  # 新增模式选择状态'PLAYING': 2,'GAME_OVER': 3
}# 修改游戏界面布局参数(新增右侧信息面板)
INFO_PANEL_WIDTH = 200  # 右侧信息面板宽度
GAME_PANEL_WIDTH = GRID_WIDTH * GRID_SIZE  # 300
#  游戏界面宽度
WINDOW_WIDTH = GAME_PANEL_WIDTH + INFO_PANEL_WIDTH
# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")# 游戏区域矩阵(0表示空)
game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]# 当前方块和位置
current_shape: Optional[List[List[int]]] = None
current_pos = [0, 0]
current_color: Optional[Tuple[int, int, int]] = None
# 在全局变量声明区域添加:
next_shape: Optional[List[List[int]]] = None
next_color: Optional[Tuple[int, int, int]] = None
score = 0
# 新增全局变量
game_mode = 0  # 0-经典模式 1-生存模式
obstacle_timer = 0
special_effect = None
effect_duration = 0# 修改new_shape函数(添加下一个方块生成)
def new_shape():global current_shape, current_pos, current_color, next_shape, next_colorif not hasattr(new_shape, "_initialized"):current_shape = random.choice(SHAPES)current_color = random.choice(COLORS)next_shape = random.choice(SHAPES)next_color = random.choice(COLORS)new_shape._initialized = Trueelse:current_shape = next_shapecurrent_color = next_colornext_shape = random.choice(SHAPES)next_color = random.choice(COLORS)if random.random() < 0.2 and current_color not in SPECIAL_COLORS:current_color = random.choice(SPECIAL_COLORS)# 修复点1:计算方块总高度shape_height = len(current_shape)# 修复点2:调整生成位置计算逻辑 ▼base_offset = -shape_height  # 确保整个方块在屏幕外# 生存模式额外上移(原逻辑错误导致坐标计算为负值不够)if game_mode == 1:base_offset = -shape_height - 2  # 调整为-2格缓冲current_pos = [GRID_WIDTH // 2 - len(current_shape[0]) // 2,base_offset  # Y坐标修正]def check_collision(shape, pos):"""统一碰撞检测(移除模式判断)"""# 修改点1:block → shapefor y in range(len(shape)):  # ← 修改这里# 修改点2:block.shape → shapefor x in range(len(shape[y])):  # ← 修改这里# 修改点3:cell → shape[y][x]if shape[y][x]:  # ← 修改这里(原cell未定义)px = pos[0] + xpy = pos[1] + y# 边界检测if px < 0 or px >= GRID_WIDTH:return Trueif py >= GRID_HEIGHT:  # 底部边界return True# 有效区域检测(包含顶部边界)if py >= 0 and game_area[py][px] is not None:return Truereturn Falsedef merge_shape():"""将当前方块合并到游戏区域"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:game_area[current_pos[1] + y][current_pos[0] + x] = current_colordef clear_lines():"""消除满行并更新分数"""global score, fall_speed, game_arealines_to_clear = [i for i, row in enumerate(game_area) if all(cell is not None for cell in row)]# 删除并补充新行(保持总行数不变)for _ in lines_to_clear:del game_area[0]  # 删除顶部行(原逻辑错误:删除指定索引行)game_area.append([None] * GRID_WIDTH)  # 在底部补充新行score += len(lines_to_clear) * 100fall_speed = max(50, 500 - (score // 100) * 50)  # 每得100分加快50msdef rotate_shape():"""旋转当前方块(顺时针)"""global current_shaperotated = [list(row) for row in zip(*current_shape[::-1])]  # 转换为列表的列表if not check_collision(rotated, current_pos):current_shape = rotateddef draw_grid():"""绘制游戏区域(增加维度保护)"""assert len(game_area) == GRID_HEIGHT, \f"游戏区域行数异常:{len(game_area)}(应保持{GRID_HEIGHT}行)"assert all(len(row) == GRID_WIDTH for row in game_area), \"游戏区域列数异常"for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = game_area[y][x]# 加颜色有效性验证(必须为三元组且数值合法)if color is not None and isinstance(color, tuple) and len(color) == 3:pygame.draw.rect(screen, color, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))def draw_current_shape():"""绘制当前下落的方块"""for y, row in enumerate(current_shape):for x, cell in enumerate(row):if cell:px = (current_pos[0] + x) * GRID_SIZEpy = (current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, current_color, (px, py, GRID_SIZE - 1, GRID_SIZE - 1))# 新增右侧信息面板绘制函数
def draw_info_panel(score, highscore, next_shape, next_color, mode, effect):# 绘制右侧面板背景pygame.draw.rect(screen, BLACK, (GAME_PANEL_WIDTH, 0, INFO_PANEL_WIDTH, WINDOW_HEIGHT))# 统一字体加载(修改关键部分)main_font = load_font("simhei", "normal")  # 使用预设的24号字small_font = load_font("simhei", "subtitle")  # 使用28号字# 修改显示文本为中文# 显示下一个方块标题(修正坐标计算)title_text = main_font.render("下一个方块", True, WHITE)title_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - title_text.get_width()) // 2screen.blit(title_text, (title_x, 30))  # 原100改为30避免重叠# 分数显示修正(使用统一字体)score_text = main_font.render(f"当前分数:{score}", True, WHITE)screen.blit(score_text, (GAME_PANEL_WIDTH + 10, 300))  # 原使用Font(None)处# 显示最高分highscore_text = main_font.render(f"最高纪录:{highscore}", True, WHITE)screen.blit(highscore_text, (GAME_PANEL_WIDTH + 10, 350))# 计算预览方块位置(居中显示)preview_size = len(next_shape[0]) * GRID_SIZEstart_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - preview_size) // 2start_y = 100# 绘制预览方块for y, row in enumerate(next_shape):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, next_color, (start_x + x * GRID_SIZE,start_y + y * GRID_SIZE,GRID_SIZE - 1, GRID_SIZE - 1))# 添加模式显示mode_text = main_font.render(  # 使用已定义的main_fontf"模式:{'生存' if mode else '经典'}",True,(255, 0, 0) if mode else (0, 255, 0))screen.blit(mode_text, (GAME_PANEL_WIDTH + 10, 400))# 显示当前特效if effect:effect_mapping = {'speed': '加速', 'shield': '护盾'}effect_text = main_font.render(  # 使用已定义的main_fontf"特效:{effect_mapping.get(effect, '未知')}",True,(255, 255, 0))screen.blit(effect_text, (GAME_PANEL_WIDTH + 10, 450))# 新增开始界面
def show_start_screen(highscore):# 添加中文字体支持try:title_font = pygame.font.SysFont("SimHei", 36)text_font = pygame.font.SysFont("SimHei", 24)except:try:title_font = pygame.font.Font("msyh.ttc", 36)text_font = pygame.font.Font("msyh.ttc", 24)except:title_font = pygame.font.Font(None, 36)text_font = pygame.font.Font(None, 24)screen.fill(BLACK)title = title_font.render("俄罗斯方块", True, WHITE)title_rect = title.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 70))screen.blit(title, title_rect)font = pygame.font.Font(None, 32)prompt = title_font.render("按任意键开始游戏", True, WHITE)prompt_rect = prompt.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(prompt, prompt_rect)highscore_text = title_font.render(f"当前最高分: {highscore}", True, (200, 200, 200))highscore_rect = highscore_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 90))screen.blit(highscore_text, highscore_rect)pygame.display.update()waiting = Truewhile waiting:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()return Falseif event.type in (pygame.KEYDOWN, pygame.MOUSEBUTTONDOWN):waiting = Falsereturn True# 新增模式选择界面(在show_start_screen函数后添加)
def show_mode_menu():screen.fill(BLACK)# 加载中文字体的正确方式font = load_font("simhei", "subtitle")  # 28号字desc_font = load_font("simhei", "normal")  # 24号字# 打印调试信息print(f"当前使用字体: {font}")print("可用系统字体:", pygame.font.get_fonts())# 绘制标题title = font.render("选择游戏模式", True, (255, 255, 0))title_rect = title.get_rect(center=(WINDOW_WIDTH // 2, 60))screen.blit(title, title_rect)# 模式按钮参数modes = [{"text": "经典模式","desc": "标准俄罗斯方块规则","key": "1","color": (0, 255, 255),"rect": pygame.Rect(WINDOW_WIDTH // 2 - 180, 120, 360, 60)},{"text": "生存模式","desc": "每30秒生成障碍行","key": "2","color": (255, 0, 0),"rect": pygame.Rect(WINDOW_WIDTH // 2 - 180, 210, 360, 60)}]# 绘制模式选项for mode in modes:# 按钮背景pygame.draw.rect(screen, (30, 30, 30), mode["rect"], border_radius=10)# 模式名称text_surf = font.render(f"{mode['key']}. {mode['text']}", True, mode["color"])text_rect = text_surf.get_rect(left=mode["rect"].left + 20, centery=mode["rect"].centery - 15)screen.blit(text_surf, text_rect)# 模式描述desc_surf = desc_font.render(mode["desc"], True, (200, 200, 200))desc_rect = desc_surf.get_rect(left=mode["rect"].left + 20, centery=mode["rect"].centery + 15)screen.blit(desc_surf, desc_rect)# 绘制提示文字prompt = desc_font.render("使用数字键选择 或 鼠标点击选择", True, (150, 150, 150))prompt_rect = prompt.get_rect(center=(WINDOW_WIDTH // 2, 320))screen.blit(prompt, prompt_rect)pygame.display.update()while True:for event in pygame.event.get():if event.type == pygame.QUIT:pygame.quit()exit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_1: return 0if event.key == pygame.K_2: return 1if event.type == pygame.MOUSEBUTTONDOWN:mouse_pos = pygame.mouse.get_pos()for idx, mode in enumerate(modes):if mode["rect"].collidepoint(mouse_pos):return idx  # 0或1对应模式def game_loop():'''游戏主循环'''global score, game_area, current_shape, current_pos, current_color, next_shape, next_colorglobal game_mode, obstacle_timer, special_effect, effect_duration# 初始化游戏状态current_state = GAME_STATES['START']highscore = load_highscore()running = Trueclock = pygame.time.Clock()fall_time = pygame.time.get_ticks()fall_speed = 10  # 下落间隔(毫秒)while running:current_time = pygame.time.get_ticks()# 状态处理if current_state == GAME_STATES['PLAYING']:assert len(game_area) == GRID_HEIGHT, "游戏区域行数异常"assert all(len(row) == GRID_WIDTH for row in game_area), "游戏区域列数异常"if current_state == GAME_STATES['START']:if not show_start_screen(highscore):returncurrent_state = GAME_STATES['MODE_SELECT']if current_state == GAME_STATES['MODE_SELECT']:game_mode = show_mode_menu()game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]score = 0if game_mode == 1:game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]obstacle_timer = pygame.time.get_ticks()for _ in range(3):obstacle_row = [DARK_GRAY if random.random() < 0.3 else None for _ in range(GRID_WIDTH)]game_area.insert(0, obstacle_row)del game_area[-1]if hasattr(new_shape, "_initialized"):del new_shape._initializednew_shape()new_shape()current_state = GAME_STATES['PLAYING']# 事件处理for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:current_pos[0] -= 1if check_collision(current_shape, current_pos):current_pos[0] += 1if event.key == pygame.K_RIGHT:current_pos[0] += 1if check_collision(current_shape, current_pos):current_pos[0] -= 1if event.key == pygame.K_DOWN:current_pos[1] += 1if check_collision(current_shape, current_pos):current_pos[1] -= 1if event.key == pygame.K_UP:rotate_shape()if event.key == pygame.K_SPACE:  # 快速下落while not check_collision(current_shape, current_pos):current_pos[1] += 1current_pos[1] -= 1draw_current_shape()pygame.display.update()# 自动下落逻辑if current_time - fall_time > (fall_speed if special_effect != 'speed' else fall_speed // 2):current_pos[1] += 1fall_time = current_timeif check_collision(current_shape, current_pos):current_pos[1] -= 1# 经典模式立即合并if game_mode == 0:merge_shape()clear_lines()new_shape()# 生存模式特殊处理else:if (current_pos[1] + len(current_shape)) > 0:  # 底部进入可见区域merge_shape()clear_lines()new_shape()# 生存模式障碍生成if game_mode == 1:if current_time - obstacle_timer > 30000:new_row = [DARK_GRAY if random.random() < 0.7 else None for _ in range(GRID_WIDTH)]game_area.insert(0, new_row)del game_area[-1]obstacle_timer = current_time# 统一结束判断if check_collision(current_shape, current_pos) and special_effect != 'shield':# 经典模式:触顶即结束if game_mode == 0 and current_pos[1] < 0:running = False# 生存模式:完全进入后碰撞才结束elif game_mode == 1 and (current_pos[1] + len(current_shape)) >= 0:running = False# 特效处理if special_effect and effect_duration > 0:effect_duration -= clock.get_time()if effect_duration <= 0:special_effect = None# 绘制界面screen.fill(DARK_GRAY)draw_grid()draw_current_shape()draw_info_panel(score, highscore, next_shape, next_color, game_mode, special_effect)pygame.display.update()clock.tick(60)# 游戏结束处理if not running:if score > highscore:save_highscore(score)highscore = scorescreen.fill(BLACK)try:font = pygame.font.SysFont("simhei", 48)except:font = pygame.font.Font(None, 48)game_over_text = font.render("游戏结束", True, (255, 0, 0))text_rect = game_over_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 30))screen.blit(game_over_text, text_rect)score_text = font.render(f"最终得分: {score}", True, WHITE)score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(score_text, score_rect)pygame.display.update()pygame.time.wait(3000)current_state = GAME_STATES['GAME_OVER']if current_state == GAME_STATES['GAME_OVER']:if not show_start_screen(highscore):running = Falseelse:current_state = GAME_STATES['START']if __name__ == "__main__":game_loop()pygame.quit()

修改后的代码 

我测试了几次,主要之前出现的问题就是

  1. 游戏无法正常结束,当方块触碰到上方越界后,方块从最下方更新。
  2. 方块没有正常清除,当本行方块填满后他整体上移,而不是清除的效果。
  3. 游戏无法正常开始,方块下移的速度太快,开始游戏后直接结束了。
  4. 方块预览和实际出现的方块之间没有关系。

修改后游戏具备一下的特色功能:

下一个方块预览

  • 在右侧信息面板实时显示即将出现的方块形状与颜色
  • 实现方法:通过 draw_info_panel 方法中的预览方块绘制逻辑

速度递增机制

  • 得分每增加50分下落速度提升25ms(最大速度50ms)
  • 代码体现:self.fall_speed = max(50, 500 - (self.score // 50) * 25)

智能位置修正

  • 旋转时若超出边界自动尝试左右平移(rotate_shape 方法)
  • 特征:最多平移至边界,若仍碰撞则取消旋转
  • 优势:减少无效旋转操作挫败感

本地高分记录,使用 tetris_highscore.txt 文件存储历史最高分 功能点:

  • 启动时自动读取 (load_highscore)
  • 破纪录时自动保存 (save_highscore)

三维检测体系,check_collision 方法实现:

  • 底部越界检测 (py >= GRID_HEIGHT)
  • 侧边越界检测 (px < 0 or px >= GRID_WIDTH)
  • 方块重叠检测 (game_area[py][px] is not None)
# -*- coding: utf-8 -*-
import pygame
import random
import os# 初始化 Pygame
pygame.init()
os.environ['PYGAME_FREETYPE'] = '1'# 常量定义
HIGHSCORE_FILE = "tetris_highscore.txt"
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
INFO_PANEL_WIDTH = 200
GAME_PANEL_WIDTH = GRID_WIDTH * GRID_SIZE
WINDOW_WIDTH = GAME_PANEL_WIDTH + INFO_PANEL_WIDTH# 颜色定义
COLORS = [(0, 255, 255),  # I型(255, 165, 0),  # L型(0, 0, 255),  # J型(255, 255, 0),  # O型(0, 255, 0),  # S型(255, 0, 255),  # T型(255, 0, 0)  # Z型
]
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40)
WHITE = (255, 255, 255)# 方块形状定义
SHAPES = [[[1, 1, 1, 1]],[[1, 0, 0], [1, 1, 1]],[[0, 0, 1], [1, 1, 1]],[[1, 1], [1, 1]],[[0, 1, 1], [1, 1, 0]],[[0, 1, 0], [1, 1, 1]],[[1, 1, 0], [0, 1, 1]]
]# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")def load_font(size):try:return pygame.font.SysFont("simhei", size)except:return pygame.font.Font(None, size)def load_highscore():try:if os.path.exists(HIGHSCORE_FILE):with open(HIGHSCORE_FILE, 'r') as f:return int(f.read().strip() or 0)return 0except:return 0def save_highscore(score):with open(HIGHSCORE_FILE, 'w') as f:f.write(str(score))class GameState:def __init__(self):self.reset()def reset(self):self.game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]self.score = 0self.highscore = load_highscore()# 仅初始化next_shapeself.next_shape = random.choice(SHAPES)self.next_color = random.choice(COLORS)self.fall_speed = 500self.running = Trueself.initialize_shapes()  # 在此方法中生成current_shapedef initialize_shapes(self):self.current_shape = self.next_shape  # 继承next_shapeself.current_color = self.next_color# 生成新next_shapeself.next_shape = random.choice(SHAPES)self.next_color = random.choice(COLORS)self.reset_position()def reset_position(self):shape_height = len(self.current_shape)self.current_pos = [GRID_WIDTH // 2 - len(self.current_shape[0]) // 2,-shape_height + 1  # 完全在游戏区域外生成]# 如果初始位置就碰撞,说明游戏结束if self.check_collision(self.current_shape, self.current_pos):self.game_over()def check_collision(self, shape, pos):for y in range(len(shape)):for x in range(len(shape[y])):if shape[y][x]:px = pos[0] + xpy = pos[1] + yif py >= GRID_HEIGHT:return Trueif px < 0 or px >= GRID_WIDTH:return Trueif py >= 0 and self.game_area[py][px] is not None:return Truereturn Falsedef rotate_shape(self):original_shape = self.current_shapeoriginal_pos = self.current_pos.copy()# 尝试旋转rotated = [list(row) for row in zip(*original_shape[::-1])]self.current_shape = rotated# 旋转后位置修正while self.check_collision(self.current_shape, self.current_pos):if self.current_pos[0] < 0:self.current_pos[0] += 1  # 右移else:self.current_pos[0] -= 1  # 左移if self.current_pos[0] < 0 or self.current_pos[0] >= GRID_WIDTH:self.current_shape = original_shape  # 还原形状self.current_pos = original_posbreakdef merge_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = self.current_pos[0] + x  # 计算实际网格坐标py = self.current_pos[1] + y# 添加双重边界检查if 0 <= px < GRID_WIDTH and 0 <= py < GRID_HEIGHT:self.game_area[py][px] = self.current_colordef clear_lines(self):# 获取待消除行索引(从下往上检测)lines_to_clear = [i for i, row in enumerate(self.game_area) if all(cell is not None for cell in row)]if lines_to_clear:# 从下往上删除已满行(避免索引错位)for idx in reversed(lines_to_clear):del self.game_area[idx]# 在顶部补充新空行(数量=消除行数)new_rows = [[None] * GRID_WIDTH for _ in lines_to_clear]self.game_area = new_rows + self.game_area# 更新分数和速度self.score += len(lines_to_clear) * 100self.fall_speed = max(50, 500 - (self.score // 50) * 25)  # 更平缓的速度变化def draw_grid(self):for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = self.game_area[y][x]# 添加颜色类型安全检查if isinstance(color, tuple) and len(color) == 3:pygame.draw.rect(screen, color,(x * GRID_SIZE, y * GRID_SIZE,GRID_SIZE - 1, GRID_SIZE - 1))def draw_current_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = (self.current_pos[0] + x) * GRID_SIZEpy = (self.current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, self.current_color,(px, py, GRID_SIZE - 1, GRID_SIZE - 1))def draw_info_panel(self):font = load_font(24)pygame.draw.rect(screen, BLACK, (GAME_PANEL_WIDTH, 0, INFO_PANEL_WIDTH, WINDOW_HEIGHT))# 下一个方块title = font.render("下一个方块", True, WHITE)screen.blit(title, (GAME_PANEL_WIDTH + 10, 30))# 预览方块start_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - len(self.next_shape[0]) * GRID_SIZE) // 2start_y = 100for y, row in enumerate(self.next_shape):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, self.next_color,(start_x + x * GRID_SIZE, start_y + y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))# 分数显示score_text = font.render(f"分数: {self.score}", True, WHITE)screen.blit(score_text, (GAME_PANEL_WIDTH + 10, 300))highscore_text = font.render(f"最高分: {self.highscore}", True, WHITE)screen.blit(highscore_text, (GAME_PANEL_WIDTH + 10, 350))def handle_input(self):for event in pygame.event.get():if event.type == pygame.QUIT:self.running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:self.current_pos[0] -= 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] += 1elif event.key == pygame.K_RIGHT:self.current_pos[0] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] -= 1elif event.key == pygame.K_DOWN:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1elif event.key == pygame.K_UP:self.rotate_shape()elif event.key == pygame.K_SPACE:while not self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] += 1self.current_pos[1] -= 1def game_over(self):if self.score > self.highscore:save_highscore(self.score)screen.fill(BLACK)font = load_font(48)text = font.render("游戏结束", True, (255, 0, 0))text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 30))screen.blit(text, text_rect)score_text = font.render(f"得分: {self.score}", True, WHITE)score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(score_text, score_rect)pygame.display.update()pygame.time.wait(3000)self.running = Falsedef run(self):clock = pygame.time.Clock()fall_time = pygame.time.get_ticks()while self.running:current_time = pygame.time.get_ticks()self.handle_input()# 自动下落if current_time - fall_time > self.fall_speed:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1self.merge_shape()self.clear_lines()self.initialize_shapes()  # 生成新方块# 游戏结束检测if self.check_collision(self.current_shape, self.current_pos):self.game_over()fall_time = current_time# 绘制界面screen.fill(DARK_GRAY)self.draw_grid()self.draw_current_shape()self.draw_info_panel()pygame.display.update()clock.tick(60)if __name__ == "__main__":game = GameState()game.run()pygame.quit()

特殊方块

新增特殊方块的功能还是出现了几个问题:

  • 想一次性消除多行,消除后空白的地方方块没有整体下移。
  • 方块结构被破坏,出现单列下移的情况,缝隙都被填满了。
  • 普通方块无法消除本行。
  • 特殊方块的功能和普通方块冲突(比如黑色方块清除的时候只会清除周围的方块就不会清除当前行的方块了)。

结果发现还是不会改,留给有缘人了,目前是触发特殊效果后消除的地方不会下移,若修改成可以下移的话就会破坏原始的结构,不过这样玩还别有一番滋味。(虽然是存在bug,但是感觉玩起来也还不错,目前玩起来有两个显著问题,一个是触发粉色方块后不会整体下移,触发黑色方块和紫色方块后只会按照特殊方块的逻辑生效,并不会清除当前行,大家可以理解成博主“故意”设置的)

处理的顺序是黑色->紫色->粉色->普通,特殊方块全部设置成1*1的形状方便消除,功能如下:

  • 黑色方块:清除以它为中心的3*3区域
  • 紫色方块清除它所在列的所有方块
  • 粉色方块:清除它所在行及其上下一行的所有方块
# -*- coding: utf-8 -*-
import pygame
import random
import os# 初始化 Pygame
pygame.init()
os.environ['PYGAME_FREETYPE'] = '1'# 常量定义
HIGHSCORE_FILE = "tetris_highscore.txt"
WINDOW_HEIGHT = 600
GRID_SIZE = 30
GRID_WIDTH = 10
GRID_HEIGHT = 20
INFO_PANEL_WIDTH = 200
GAME_PANEL_WIDTH = GRID_WIDTH * GRID_SIZE
WINDOW_WIDTH = GAME_PANEL_WIDTH + INFO_PANEL_WIDTH# 颜色定义
COLORS = [(0, 255, 255),  # (青色)(255, 165, 0),  # (橙色)(0, 0, 255),  # (蓝色)(255, 255, 0),  # (黄色)(0, 255, 0),  # (绿色)(255, 0, 255),  # (品红色)(255, 0, 0)  # (红色)
]
# 颜色定义(原COLORS列表后添加特殊颜色)
SPECIAL_COLORS = [(0, 0, 0),  # 黑色(中心爆破)(128, 0, 128),  # 紫色(整列消除)(255, 192, 203)  # 粉色(三行消除)
]
BLACK = (0, 0, 0)
DARK_GRAY = (40, 40, 40)
WHITE = (255, 255, 255)# 方块形状定义
SHAPES = [[[1, 1, 1, 1]],  # I行[[1, 0, 0], [1, 1, 1]],  # L行[[0, 0, 1], [1, 1, 1]],  # J行[[1, 1], [1, 1]],  # S行[[0, 1, 1], [1, 1, 0]],[[0, 1, 0], [1, 1, 1]],[[1, 1, 0], [0, 1, 1]],[[1]]  # 新增特殊方块形状(放在列表最后)
]
# 初始化窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("俄罗斯方块")def load_font(size):try:return pygame.font.SysFont("simhei", size)except:return pygame.font.Font(None, size)def load_highscore():try:if os.path.exists(HIGHSCORE_FILE):with open(HIGHSCORE_FILE, 'r') as f:return int(f.read().strip() or 0)return 0except:return 0def save_highscore(score):with open(HIGHSCORE_FILE, 'w') as f:f.write(str(score))class GameState:def __init__(self):self.reset()def clear_around(self, x, y):"""以(x,y)为中心消除3x3区域"""for dy in [-1, 0, 1]:for dx in [-1, 0, 1]:nx, ny = x + dx, y + dyif 0 <= nx < GRID_WIDTH and 0 <= ny < GRID_HEIGHT:self.game_area[ny][nx] = Nonedef clear_column(self, x):"""清除整列"""for y in range(GRID_HEIGHT):self.game_area[y][x] = Nonedef clear_rows(self, y):"""清除指定行及其相邻行"""for dy in [-1, 0, 1]:if 0 <= (y + dy) < GRID_HEIGHT:self.game_area[y + dy] = [None] * GRID_WIDTHdef reset(self):self.game_area = [[None] * GRID_WIDTH for _ in range(GRID_HEIGHT)]self.score = 0self.highscore = load_highscore()# 仅初始化next_shapeself.next_shape = random.choice(SHAPES)self.next_color = random.choice(COLORS)self.fall_speed = 500self.running = Trueself.initialize_shapes()  # 在此方法中生成current_shapedef initialize_shapes(self):self.current_shape = self.next_shape  # 继承next_shapeself.current_color = self.next_color# 生成新next_shape# 30%概率生成特殊方块if random.random() < 0.3:self.next_shape = [[1]]self.next_color = random.choice(SPECIAL_COLORS)else:self.next_shape = random.choice(SHAPES[:-1])  # 排除特殊形状self.next_color = random.choice(COLORS)self.reset_position()def reset_position(self):shape_height = len(self.current_shape)self.current_pos = [GRID_WIDTH // 2 - len(self.current_shape[0]) // 2,-shape_height + 1  # 完全在游戏区域外生成]# 如果初始位置就碰撞,说明游戏结束if self.check_collision(self.current_shape, self.current_pos):self.game_over()def check_collision(self, shape, pos):for y in range(len(shape)):for x in range(len(shape[y])):if shape[y][x]:px = pos[0] + xpy = pos[1] + yif py >= GRID_HEIGHT:return Trueif px < 0 or px >= GRID_WIDTH:return Trueif py >= 0 and self.game_area[py][px] is not None:return Truereturn Falsedef rotate_shape(self):original_shape = self.current_shapeoriginal_pos = self.current_pos.copy()# 尝试旋转rotated = [list(row) for row in zip(*original_shape[::-1])]self.current_shape = rotated# 旋转后位置修正while self.check_collision(self.current_shape, self.current_pos):if self.current_pos[0] < 0:self.current_pos[0] += 1  # 右移else:self.current_pos[0] -= 1  # 左移if self.current_pos[0] < 0 or self.current_pos[0] >= GRID_WIDTH:self.current_shape = original_shape  # 还原形状self.current_pos = original_posbreakdef merge_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = self.current_pos[0] + x  # 计算实际网格坐标py = self.current_pos[1] + y# 添加双重边界检查if 0 <= px < GRID_WIDTH and 0 <= py < GRID_HEIGHT:self.game_area[py][px] = self.current_colordef clear_lines(self):lines_cleared = []while True:# 标准行消除full_lines = [i for i, row in enumerate(self.game_area)if all(cell is not None for cell in row)]if not full_lines: break# 处理特殊方块for y in full_lines:for x in range(GRID_WIDTH):color = self.game_area[y][x]if color == (0, 0, 0):  # 黑色方块self.clear_around(x, y)elif color == (128, 0, 128):  # 紫色方块self.clear_column(x)elif color == (255, 192, 203):  # 粉色方块self.clear_rows(y)# 更新游戏区域new_grid = [row for row in self.game_areaif not all(cell is not None for cell in row)]new_rows = GRID_HEIGHT - len(new_grid)self.game_area = [[None] * GRID_WIDTH for _ in range(new_rows)] + new_gridlines_cleared.extend(full_lines)# 分数计算(每个特殊方块额外加分)self.score += len(lines_cleared) * 100self.score += sum(20 for y in lines_clearedfor cell in self.game_area[y]if cell in SPECIAL_COLORS)def draw_grid(self):for y in range(GRID_HEIGHT):for x in range(GRID_WIDTH):color = self.game_area[y][x]# 添加颜色类型安全检查if isinstance(color, tuple) and len(color) == 3:pygame.draw.rect(screen, color,(x * GRID_SIZE, y * GRID_SIZE,GRID_SIZE - 1, GRID_SIZE - 1))def draw_current_shape(self):for y, row in enumerate(self.current_shape):for x, cell in enumerate(row):if cell:px = (self.current_pos[0] + x) * GRID_SIZEpy = (self.current_pos[1] + y) * GRID_SIZEpygame.draw.rect(screen, self.current_color,(px, py, GRID_SIZE - 1, GRID_SIZE - 1))def draw_info_panel(self):font = load_font(24)pygame.draw.rect(screen, BLACK, (GAME_PANEL_WIDTH, 0, INFO_PANEL_WIDTH, WINDOW_HEIGHT))# 下一个方块title = font.render("下一个方块", True, WHITE)screen.blit(title, (GAME_PANEL_WIDTH + 10, 30))# 预览方块start_x = GAME_PANEL_WIDTH + (INFO_PANEL_WIDTH - len(self.next_shape[0]) * GRID_SIZE) // 2start_y = 100for y, row in enumerate(self.next_shape):for x, cell in enumerate(row):if cell:pygame.draw.rect(screen, self.next_color,(start_x + x * GRID_SIZE, start_y + y * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1))# 分数显示score_text = font.render(f"分数: {self.score}", True, WHITE)screen.blit(score_text, (GAME_PANEL_WIDTH + 10, 300))highscore_text = font.render(f"最高分: {self.highscore}", True, WHITE)screen.blit(highscore_text, (GAME_PANEL_WIDTH + 10, 350))def handle_input(self):for event in pygame.event.get():if event.type == pygame.QUIT:self.running = Falseif event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:self.current_pos[0] -= 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] += 1elif event.key == pygame.K_RIGHT:self.current_pos[0] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[0] -= 1elif event.key == pygame.K_DOWN:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1elif event.key == pygame.K_UP:self.rotate_shape()elif event.key == pygame.K_SPACE:while not self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] += 1self.current_pos[1] -= 1def game_over(self):if self.score > self.highscore:save_highscore(self.score)screen.fill(BLACK)font = load_font(48)text = font.render("游戏结束", True, (255, 0, 0))text_rect = text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 30))screen.blit(text, text_rect)score_text = font.render(f"得分: {self.score}", True, WHITE)score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 30))screen.blit(score_text, score_rect)pygame.display.update()pygame.time.wait(3000)self.running = Falsedef run(self):clock = pygame.time.Clock()fall_time = pygame.time.get_ticks()while self.running:current_time = pygame.time.get_ticks()self.handle_input()# 自动下落if current_time - fall_time > self.fall_speed:self.current_pos[1] += 1if self.check_collision(self.current_shape, self.current_pos):self.current_pos[1] -= 1self.merge_shape()self.clear_lines()self.initialize_shapes()  # 生成新方块# 游戏结束检测if self.check_collision(self.current_shape, self.current_pos):self.game_over()fall_time = current_time# 绘制界面screen.fill(DARK_GRAY)self.draw_grid()self.draw_current_shape()self.draw_info_panel()pygame.display.update()clock.tick(60)if __name__ == "__main__":game = GameState()game.run()pygame.quit()

总结

  1. 先使用DeepSeek生成可以执行的代码
  2. 使用Lingma优化代码
  3. 使用Lingma增加特色功能(建议不要一次性增加多个模块,可以一个个模块进行增加调试,对相对满意的模块可以先进行保存)
  4. 可以通过Ctrl+F调出搜索界面实现快速定位,可以询问Lingma解决警告和报错信息。

当然有Python基础的当然可以理解一下代码的逻辑然后进行修改,但是像我这种什么都不懂的同学就只能以AI为主,通过人工辅助询问一些问题来开发自己的小游戏,个人感觉非常消耗时间,最后如果有什么问题可以在评论区留言,欢迎各位大佬来批评指正!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/81850.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin带接收者的Lambda介绍和应用(封装DialogFragment)

先来看一个具体应用&#xff1a;假设我们有一个App&#xff0c;App中有一个退出应用的按钮&#xff0c;点击该按钮后并不是立即退出&#xff0c;而是先弹出一个对话框&#xff0c;询问用户是否确定要退出&#xff0c;用户点了确定再退出&#xff0c;点取消则不退出&#xff0c;…

ES6/ES11知识点 续一

模板字符串 在 ECMAScript&#xff08;ES&#xff09;中&#xff0c;模板字符串&#xff08;Template Literals&#xff09;是一种非常强大的字符串表示方式&#xff0c;它为我们提供了比传统字符串更灵活的功能&#xff0c;尤其是在处理动态内容时。模板字符串通过反引号&…

【C++】智能指针RALL实现shared_ptr

个人主页 &#xff1a; zxctscl 专栏 【C】、 【C语言】、 【Linux】、 【数据结构】、 【算法】 如有转载请先通知 文章目录 1. 为什么需要智能指针&#xff1f;2. 内存泄漏2.1 什么是内存泄漏&#xff0c;内存泄漏的危害2.2 内存泄漏分类&#xff08;了解&#xff09;2.3 如何…

ROS2 开发踩坑记录(持续更新...)

1. 从find_package(xxx REQUIRED)说起&#xff0c;如何引用其他package(包&#xff09; 查看包的安装位置和include路径详细文件列表 例如&#xff0c;xxx包名为pluginlib # 查看 pluginlib 的安装位置 dpkg -L ros-${ROS_DISTRO}-pluginlib | grep include 这条指令的目的是…

系统思考:困惑源于内心假设

不要怀疑&#xff0c;你的困惑来自你的假设。 你是否曾经陷入过无解的困境&#xff0c;觉得外部环境太复杂&#xff0c;自己的处境无法突破&#xff1f;很多时候&#xff0c;答案并不在于外部的局势&#xff0c;而是来自我们内心深处的假设——那些我们理所当然、从未质疑过的…

GitHub修炼法则:第一次提交代码教学(Liunx系统)

前言 github是广大程序员们必须要掌握的一个技能&#xff0c;万事开头难&#xff0c;如果成功提交了第一次代码&#xff0c;那么后来就会简单很多。网上的相关资料往往都不是从第一次开始&#xff0c;导致很多新手们会在过程中遇到很多权限认证相关的问题&#xff0c;进而被卡…

沥青路面裂缝的目标检测与图像分类任务

文章题目是《A grid‐based classification and box‐based detection fusion model for asphalt pavement crack》 于2023年发表在《Computer‐Aided Civil and Infrastructure Engineering》 论文采用了一种基于网格分类和基于框的检测&#xff08;GCBD&#xff09;&#xff…

【Flask】ORM模型以及数据库迁移的两种方法(flask-migrate、Alembic)

ORM模型 在Flask中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;模型是指使用面向对象的方式来操作数据库的编程技术。它允许开发者使用Python类和对象来操作数据库&#xff0c;而不需要直接编写SQL语句。 核心概念 1. ORM模型…

C/C++滑动窗口算法深度解析与实战指南

C/C滑动窗口算法深度解析与实战指南 引言 滑动窗口算法是解决数组/字符串连续子序列问题的利器&#xff0c;通过动态调整窗口边界&#xff0c;将暴力解法的O(n)时间复杂度优化至O(n)。本文将系统讲解滑动窗口的核心原理、C/C实现技巧及经典应用场景&#xff0c;助您掌握这一高…

Vuex使用指南:状态管理

一、什么是状态管理&#xff1f;为什么需要 Vuex&#xff1f; 1. 状态管理的基本概念 在 Vue 应用中&#xff0c;状态指的是应用中的数据。例如&#xff1a; 用户登录状态购物车中的商品文章列表的分页信息 状态管理就是对这些数据的创建、读取、更新和删除进行有效管理。 …

【信息系统项目管理师-论文真题】2007下半年论文详解(包括解题思路和写作要点)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题1:大型项目的计划与监控1、写作要点2、解题思路大型信息系统项目的组织制订大型信息系统项目进度计划的方法试题2:组织级项目管理的绩效考核1、写作要点2、解题思路在项目考核过程中会遇到哪些问题项目的…

项目管理学习-CSPM(1)

01引言 最近在学习CSPM的课程&#xff0c;有部分的内容自己还是受益匪浅的&#xff0c;建议有需要提升项目管理能力的同学可以以考促学的方式进行学习&#xff0c;下面整理了一部分内容和大家分享和学习。CSPM全称 China Standards Project Management&#xff0c;中文名项目管…

介绍分治、动态规划、回溯分别是什么?有什么联系和区别?给出对象的场景和java代码?

一、分治算法&#xff08;Divide and Conquer&#xff09; 概念&#xff1a; 分治算法是将一个复杂问题分成若干个子问题&#xff0c;每个子问题结构与原问题类似&#xff0c;然后递归地解决这些子问题&#xff0c;最后将子问题的结果合并得到原问题的解。 特点&#xff1a;…

解锁DeepSeek模型微调:从小白到高手的进阶之路

目录 一、DeepSeek 模型初相识二、探秘微调原理2.1 迁移学习基础2.2 微调的参数更新机制 三、数据准备3.1 数据收集3.2 数据标注3.3 数据预处理 四、模型选择与加载4.1 选择合适的预训练模型4.2 加载模型 五、微调训练实战5.1 确定微调策略5.2 设置训练参数5.3 训练过程 六、模…

端到端观测分析:从前端负载均衡到后端服务

前言 我们在做系统运维保障的时候&#xff0c;关注从前端负载均衡到后端服务的流量情况是很有必要的&#xff0c;可以了解每个后端服务实例接收的流量大小&#xff0c;这有助于确定资源分配是否合理&#xff0c;能够帮助找出后端服务中的性能瓶颈。同时&#xff0c;当系统出现…

Ubuntu下OCC7.9+Qt5 快速搭建3D可视化框架

Ubuntu下OCC7.9+Qt5搭建简易的项目框架 近两年国产CAD替代如日中天,而几何内核作为CAD软件的核心组件之一,当前有且仅有唯一开源的几何内核库即OCCT;这里为各位自立于投入CAD开发或正在学习OCC库的小伙伴们奉献上一个快速搭建QT+OCC的项目框架; 本文介绍了Qt5+Occ 显示几何…

C++类与对象—下:夯实面向对象编程的阶梯

9. 赋值运算符重载 9.1 运算符重载 在 C 里&#xff0c;运算符重载能够让自定义类型的对象像内置类型那样使用运算符&#xff0c;这极大地提升了代码的可读性与可维护性。运算符重载本质上是一种特殊的函数&#xff0c;其函数名是 operator 加上要重载的运算符。 下面是运算…

【深度学习-Day 6】掌握 NumPy:ndarray 创建、索引、运算与性能优化指南

Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…

工程师 - 汽车分类

欧洲和中国按字母对汽车分类&#xff1a; **轴距**&#xff1a;简单来说&#xff0c;就是前轮中心点到后轮中心点之间的距离&#xff0c;也就是前轮轴和后轮轴之间的长度。根据轴距的大小&#xff0c;国际上通常把轿车分为以下几类&#xff08;德国大众汽车习惯用A\B\C\D分类&a…

[低代码 + AI] 明道云与 Dify 的三种融合实践方式详解

随着低代码平台和大语言模型工具的不断发展,将企业数据与智能交互能力融合,成为提高办公效率与自动化水平的关键一步。明道云作为一款成熟的低代码平台,Dify 则是一个支持自定义工作流的开源 LLM 应用框架。两者结合,可以实现灵活、高效的智能化业务处理。 本文将详解明道…