Greedy snake 2.0.py

import pygame
import random
import copy
import sys
import math

初始化pygame

pygame.init()

设置屏幕大小

screen_width, screen_height = 500, 500
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('贪吃蛇小游戏')

颜色定义

WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255) # 电脑蛇颜色

字体

font = pygame.font.SysFont('simhei', 40)
small_font = pygame.font.SysFont('simhei', 30) # 新增小字体

食物数量

FOOD_COUNT = 8

def draw_button(text, x, y, width, height, inactive_color, active_color, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()

if x < mouse[0] < x + width and y < mouse[1] < y + height:
    pygame.draw.rect(screen, active_color, (x, y, width, height))
    if click[0] == 1 and action is not None:
        return action
else:
    pygame.draw.rect(screen, inactive_color, (x, y, width, height))

text_surf = font.render(text, True, BLACK)
text_rect = text_surf.get_rect()
text_rect.center = (x + width / 2, y + height / 2)
screen.blit(text_surf, text_rect)

return False

def game_intro():
intro = True
clock = pygame.time.Clock()

while intro:
    clock.tick(15)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    screen.fill(WHITE)
    title = font.render("贪吃蛇游戏", True, BLACK)
    title_rect = title.get_rect(center=(screen_width / 2, screen_height / 3))
    screen.blit(title, title_rect)

    start_game = draw_button("游戏开始",
                             screen_width / 2 - 100,
                             screen_height / 2,
                             200,
                             50,
                             GREEN,
                             (0, 200, 0),
                             "start")

    if start_game == "start":
        intro = False

    pygame.display.update()

def get_distance(p1, p2):
return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2)

def computer_ai(snake_list, foods):
head = snake_list[0]

closest_food = None
min_dist = float('inf')
for food in foods:
    dist = get_distance(head, food["pos"])
    if dist < min_dist:
        min_dist = dist
        closest_food = food["pos"]

if closest_food is None:
    return "up"

directions = [
    ([head[0], head[1] - 10], "up"),
    ([head[0], head[1] + 10], "down"),
    ([head[0] - 10, head[1]], "left"),
    ([head[0] + 10, head[1]], "right")
]

valid_directions = []
for new_pos, direction in directions:
    if 0 <= new_pos[0] < 500 and 0 <= new_pos[1] < 500:
        collision = False
        for segment in snake_list[:-1]:
            if new_pos == segment:
                collision = True
                break
        if not collision:
            valid_directions.append((new_pos, direction))

if not valid_directions:
    return "up"

best_dir = None
min_dist = float('inf')
for new_pos, direction in valid_directions:
    dist = get_distance(new_pos, closest_food)
    if dist < min_dist:
        min_dist = dist
        best_dir = direction

return best_dir

def generate_food(count):
foods = []
for _ in range(count):
food = {
"pos": [random.randint(15, 485), random.randint(15, 485)],
"color": RED
}
foods.append(food)
return foods

def game_loop():
snake_list = [[10, 10]]
direction = "right"
next_direction = "right"

computer_snake = [[250, 250]]
computer_dir = "right"

foods = generate_food(FOOD_COUNT)

running = True
game_over_reason = ""  # 新增:存储游戏结束原因
clock = pygame.time.Clock()

while running:
    clock.tick(15)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                next_direction = "up"
            elif event.key == pygame.K_DOWN:
                next_direction = "down"
            elif event.key == pygame.K_LEFT:
                next_direction = "left"
            elif event.key == pygame.K_RIGHT:
                next_direction = "right"

    direction = next_direction

    screen.fill(WHITE)

    # 绘制食物
    food_rects = []
    for food in foods:
        rect = pygame.draw.circle(screen, food["color"], food["pos"], 13, 0)
        food_rects.append({"rect": rect, "pos": food["pos"], "color": food["color"]})

    # 电脑AI决策
    computer_dir = computer_ai(computer_snake, foods)

    computer_move_up = computer_dir == "up"
    computer_move_down = computer_dir == "down"
    computer_move_left = computer_dir == "left"
    computer_move_right = computer_dir == "right"

    # 绘制玩家蛇
    player_snake_rect = []
    for snake_point in snake_list:
        player_snake_rect_point = pygame.draw.circle(screen, GREEN, snake_point, 6, 0)
        player_snake_rect.append(player_snake_rect_point)

    # 检查玩家蛇吃食物
    eaten_indices = []
    for i, food in enumerate(food_rects):
        if food["rect"].collidepoint(snake_list[0]):  # 只检查蛇头
            eaten_indices.append(i)
            snake_list.append(food["pos"])

    # 移除被吃掉的食物并生成新食物
    for i in sorted(eaten_indices, reverse=True):
        if i < len(foods):
            foods.pop(i)
    if eaten_indices:
        foods.extend(generate_food(len(eaten_indices)))

    # 绘制电脑蛇
    computer_snake_rect = []
    for snake_point in computer_snake:
        computer_snake_rect_point = pygame.draw.circle(screen, BLUE, snake_point, 5, 0)
        computer_snake_rect.append(computer_snake_rect_point)

    # 检查电脑蛇吃食物
    eaten_indices = []
    for i, food in enumerate(food_rects):
        if food["rect"].collidepoint(computer_snake[0]):  # 只检查电脑蛇头
            eaten_indices.append(i)
            computer_snake.append(food["pos"])

    # 移除被吃掉的食物并生成新食物
    for i in sorted(eaten_indices, reverse=True):
        if i < len(foods):
            foods.pop(i)
    if eaten_indices:
        foods.extend(generate_food(len(eaten_indices)))

    # 移动玩家蛇
    pos = len(snake_list) - 1
    while pos > 0:
        snake_list[pos] = copy.deepcopy(snake_list[pos - 1])
        pos -= 1

    # 根据方向移动蛇头
    if direction == "up":
        snake_list[0][1] -= 10
        if snake_list[0][1] < 0:
            snake_list[0][1] = 500
    elif direction == "down":
        snake_list[0][1] += 10
        if snake_list[0][1] > 500:
            snake_list[0][1] = 0
    elif direction == "left":
        snake_list[0][0] -= 10
        if snake_list[0][0] < 0:
            snake_list[0][0] = 500
    elif direction == "right":
        snake_list[0][0] += 10
        if snake_list[0][0] > 500:
            snake_list[0][0] = 0

    # 移动电脑蛇
    pos = len(computer_snake) - 1
    while pos > 0:
        computer_snake[pos] = copy.deepcopy(computer_snake[pos - 1])
        pos -= 1

    if computer_move_up:
        computer_snake[0][1] -= 10
        if computer_snake[0][1] < 0:
            computer_snake[0][1] = 500
    if computer_move_down:
        computer_snake[0][1] += 10
        if computer_snake[0][1] > 500:
            computer_snake[0][1] = 0
    if computer_move_left:
        computer_snake[0][0] -= 10
        if computer_snake[0][0] < 0:
            computer_snake[0][0] = 500
    if computer_move_right:
        computer_snake[0][0] += 10
        if computer_snake[0][0] > 500:
            computer_snake[0][0] = 0

    # 检查碰撞
    head_rest = player_snake_rect[0]
    count = len(player_snake_rect)
    while count > 1:
        if head_rest.colliderect(player_snake_rect[count - 1]):
            game_over_reason = "你撞到了自己!"
            running = True
        count -= 1

    computer_head_rest = computer_snake_rect[0]
    count = len(computer_snake_rect)
    while count > 1:
        if computer_head_rest.colliderect(computer_snake_rect[count - 1]):
            computer_snake = computer_snake[:1]
        count -= 1

    for segment in computer_snake_rect:
        if head_rest.colliderect(segment):
            game_over_reason = "你撞到了电脑蛇!"
            running = False

    pygame.display.update()

# 游戏结束画面
screen.fill(WHITE)
game_over = font.render("游戏结束", True, BLACK)
reason = small_font.render(game_over_reason, True, BLACK)  # 显示游戏结束原因
restart = font.render("按任意键重新开始", True, BLACK)

screen.blit(game_over, (screen_width / 2 - game_over.get_width() / 2, screen_height / 3 - 30))
screen.blit(reason, (screen_width / 2 - reason.get_width() / 2, screen_height / 3 + 20))  # 显示原因
screen.blit(restart, (screen_width / 2 - restart.get_width() / 2, screen_height / 2 + 30))

pygame.display.update()

waiting = True
while waiting:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN:
            waiting = False

游戏主循环

while True:
game_intro()
game_loop()

pygame.quit()

posted @ 2025-06-17 16:26  渔樵伴夜归客  阅读(9)  评论(0)    收藏  举报