让deepseek玩贪吃蛇

官方api调用有点慢,只实现了一些基础功能。

在这里插入图片描述

import pygame
import random
import requests
import time
from openai import OpenAI

# 初始化参数
WIDTH, HEIGHT = 400, 400
GRID_SIZE = 20
client = OpenAI(api_key="sk-2af2*********", base_url="https://api.deepseek.com")

# 在文件顶部添加导入
import openai
import threading
from queue import Queue

# 在全局参数部分修改
CONVERSATION_HISTORY = []  # 重命名为对话历史
MAX_HISTORY = 10  # 增加历史记录容量

def get_direction_from_api(snake, food, direction, conversation_history):
    """修改提示生成部分"""
    head = snake[0]
    
    # 新增方向元组定义
    directions = [(0, -1), (0, 1), (-1, 0), (1, 0)]  # 上、下、左、右
    
    # 构建障碍物检测提示
    obstacles = []
    for distance in range(1, 6):
        check_pos = (
            head[0] + direction[0] * distance * GRID_SIZE,
            head[1] + direction[1] * distance * GRID_SIZE
        )
        if (check_pos in snake[1:] or 
            not (0 <= check_pos[0] < WIDTH and 0 <= check_pos[1] < HEIGHT)):
            obstacles.append(str(distance))
    
    # 构建食物检测提示
    food_dir = ""
    if food[0] > head[0]: food_dir = "right"
    elif food[0] < head[0]: food_dir = "left"
    elif food[1] > head[1]: food_dir = "down"
    elif food[1] < head[1]: food_dir = "up"
    
    # 修复处:处理初始静止状态
    current_dir = "未移动" if direction == (0,0) else ['up','down','left','right'][directions.index(direction)]
    prompt = f"当前方向:{current_dir}。"
    prompt += f"前方障碍在距离:{','.join(obstacles)}格。" if obstacles else "前方无近距离障碍。"
    prompt += f"食物位于你的{food_dir}方,距离X轴{abs(food[0]-head[0])//GRID_SIZE}格,Y轴{abs(food[1]-head[1])//GRID_SIZE}格。"
    
    # 添加碰撞历史到提示
    if conversation_history:
        prompt += f"\n最近{MAX_HISTORY}条对话记录:\n" + "\n".join(
            [f"{i+1}. {msg}" for i, msg in enumerate(conversation_history[-MAX_HISTORY:])]
        )

    try:
        response = client.chat.completions.create(
            model="deepseek-reasoner",
            messages=[{
                "role": "user",
                "content": prompt + "\n请用单个方向词(up/down/left/right)回答"
            }],
            timeout=300
        )
        
        print(f"[API请求] {prompt}")
        print(f"[API响应] {response}")
        
        choice = response.choices[0].message.content.strip().lower()
        return {
            "up": (0, -1), "down": (0, 1),
            "left": (-1, 0), "right": (1, 0)
        }.get(choice, direction)
        
    except openai.APIError as e:
        print(f"OpenAI API错误: {e}")
        return direction

def reset_game():
    """重置游戏状态"""
    return {
        'snake': [(WIDTH//2, HEIGHT//2)],
        'food': (random.randrange(0, WIDTH, GRID_SIZE), 
                random.randrange(0, HEIGHT, GRID_SIZE)),
        'direction': (0, 0),
        'last_api_call': time.time(),
        'growth_pending': 0
    }

# 在import区域新增
import threading
from queue import Queue

# 在全局参数新增
direction_queue = Queue()
api_requesting = False  # API请求状态标志

def get_direction_async(snake, food, direction, conversation_history):
    """异步获取方向"""
    global api_requesting
    try:
        new_dir = get_direction_from_api(snake, food, direction, conversation_history)
        direction_queue.put(new_dir)
    finally:
        api_requesting = False

def game_loop():
    pygame.init()
    screen = pygame.display.set_mode((WIDTH, HEIGHT))
    clock = pygame.time.Clock()
    
    game_state = reset_game()
    collision_history = []
    global api_requesting  # 新增全局变量声明

    while True:
        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                return
                
        # 修改API调用部分为异步
        if not api_requesting and (time.time() - game_state['last_api_call'] > 0.5):
            api_requesting = True
            threading.Thread(target=get_direction_async, args=(
                game_state['snake'], 
                game_state['food'],
                game_state['direction'],
                CONVERSATION_HISTORY[-MAX_HISTORY:] if CONVERSATION_HISTORY else []  # 修复参数
            )).start()
            game_state['last_api_call'] = time.time()
        
        # 处理方向队列中的新方向
        # 修改后的移动逻辑
        if not direction_queue.empty():
            game_state['direction'] = direction_queue.get()
            # 执行单步移动
            new_head = (
                game_state['snake'][0][0] + game_state['direction'][0] * GRID_SIZE,
                game_state['snake'][0][1] + game_state['direction'][1] * GRID_SIZE
            )
            
            # 碰撞检测
            if (new_head in game_state['snake'] or 
                not (0 <= new_head[0] < WIDTH and 0 <= new_head[1] < HEIGHT)):
                print("撞到障碍物!停止移动")
                # 停止移动并保持当前状态
                game_state['direction'] = (0, 0)
                game_state['last_api_call'] = time.time()
                continue  # 跳过后续移动逻辑
                
            # 移动蛇并处理食物
            game_state['snake'].insert(0, new_head)
            if new_head == game_state['food']:
                game_state['food'] = (random.randrange(0, WIDTH, GRID_SIZE),
                                    random.randrange(0, HEIGHT, GRID_SIZE))
                while game_state['food'] in game_state['snake']:
                    game_state['food'] = (random.randrange(0, WIDTH, GRID_SIZE),
                                        random.randrange(0, HEIGHT, GRID_SIZE))
                game_state['growth_pending'] += 1
            else:
                if game_state['growth_pending'] > 0:
                    game_state['growth_pending'] -= 1
                else:
                    game_state['snake'].pop()
            
            # 移动后立即停止并重置方向
            game_state['direction'] = (0, 0)
            game_state['last_api_call'] = time.time()

        # 保持API调用持续进行(原0.5秒间隔限制移除)
        if not api_requesting:
            api_requesting = True
            threading.Thread(target=get_direction_async, args=(
                game_state['snake'], 
                game_state['food'],
                game_state['direction'],
                CONVERSATION_HISTORY[-MAX_HISTORY:] if CONVERSATION_HISTORY else []  # 修复参数
            )).start()
        
        # 绘制界面
        screen.fill((0,0,0))
        for segment in game_state['snake']:  # 修复snake引用
            pygame.draw.rect(screen, (0,255,0), 
                           (segment[0], segment[1], GRID_SIZE-1, GRID_SIZE-1))
        pygame.draw.rect(screen, (255,0,0),
                        (game_state['food'][0], game_state['food'][1], GRID_SIZE-1, GRID_SIZE-1))  # 修复food引用
        pygame.display.flip()
        clock.tick(10)

if __name__ == "__main__":
    game_loop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值