贪吃蛇游戏自动控制程序
贪吃蛇游戏自动控制程序
本程序包含两个 Python 文件:snake_game.py 和 auto_snake.py。
snake_game.py
import pygame
import random
# 定义游戏区域大小和格子大小
screen_width = 500
screen_height = 500
snake_block_size = 10
# 初始化Pygame库
pygame.init()
# 创建游戏窗口和字体对象
font_style = pygame.font.SysFont(None, 50)
game_window = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('贪吃蛇')
# 定义颜色常量
white = (255, 255, 255)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
# 在屏幕上显示消息
def message(msg, color):
mesg = font_style.render(msg, True, color)
game_window.blit(mesg, [screen_width / 6, screen_height / 3])
# 主函数
def gameLoop():
# 初始化贪吃蛇位置、长度和方向
x1 = screen_width / 2
y1 = screen_height / 2
x1_change = 0
y1_change = 0
snake_List = []
Length_of_snake = 1
# 初始化食物位置
foodx = round(random.randrange(0, screen_width - snake_block_size) / 10.0) * 10.0
foody = round(random.randrange(0, screen_height - snake_block_size) / 10.0) * 10.0
# 贪吃蛇主循环
game = True
while game:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 点击关闭按钮退出游戏
game = False
# 按键控制方向
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -snake_block_size
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = snake_block_size
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -snake_block_size
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = snake_block_size
x1_change = 0
# 更新贪吃蛇位置
x1 += x1_change
y1 += y1_change
# 判断是否撞墙
if x1 >= screen_width or x1 < 0 or y1 >= screen_height or y1 < 0:
game = False
break
# 绘制贪吃蛇和食物
game_window.fill(black)
pygame.draw.rect(game_window, green, [foodx, foody, snake_block_size, snake_block_size])
pygame.draw.rect(game_window, white, [x1, y1, snake_block_size, snake_block_size])
# 将当前贪吃蛇头的位置加入到贪吃蛇列表的第一个元素
snake_Head = [x1, y1]
snake_List.append(snake_Head)
# 如果贪吃蛇长度超过定义的初始值,移除贪吃蛇最后一个格子(除了头之外)
if len(snake_List) > Length_of_snake:
del snake_List[0]
# 判断是否撞到自己
for x in snake_List[:-1]:
if x == snake_Head:
game = False
break
# 更新食物位置和贪吃蛇长度
pygame.display.update()
if x1 == foodx and y1 == foody:
foodx = round(random.randrange(0, screen_width - snake_block_size) / 10.0) * 10.0
foody = round(random.randrange(0, screen_height - snake_block_size) / 10.0) * 10.0
Length_of_snake += 1
# 控制游戏帧率
clock = pygame.time.Clock()
clock.tick(30)
# 关闭游戏窗口并退出Pygame库
pygame.quit()
quit()
# 运行主函数
gameLoop()
auto_snake.py
import pygame
import time
import random
import cv2
import pyautogui
from PIL import ImageGrab
# 定义游戏区域大小和格子大小
screen_width = 500
screen_height = 500
snake_block_size = 10
# 初始化Pygame库
pygame.init()
# 创建游戏窗口和字体对象
font_style = pygame.font.SysFont(None, 50)
game_window = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('贪吃蛇')
# 定义颜色常量
white = (255, 255, 255)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
# 在屏幕上显示消息
def message(msg, color):
mesg = font_style.render(msg, True, color)
game_window.blit(mesg, [screen_width / 6, screen_height / 3])
# 主函数
def gameLoop():
# 初始化贪吃蛇位置、长度和方向
x1 = screen_width / 2
y1 = screen_height / 2
x1_change = 0
y1_change = 0
snake_List = []
Length_of_snake = 1
# 初始化食物位置
foodx = round(random.randrange(0, screen_width - snake_block_size) / 10.0) * 10.0
foody = round(random.randrange(0, screen_height - snake_block_size) / 10.0) * 10.0
# 贪吃蛇主循环
game = True
while game:
for event in pygame.event.get():
if event.type == pygame.QUIT: # 点击关闭按钮退出游戏
game = False
# 按键控制方向
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -snake_block_size
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = snake_block_size
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -snake_block_size
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = snake_block_size
x1_change = 0
# 更新贪吃蛇位置
x1 += x1_change
y1 += y1_change
# 判断是否撞墙
if x1 >= screen_width or x1 < 0 or y1 >= screen_height or y1 < 0:
game = False
break
# 绘制贪吃蛇和食物
game_window.fill(black)
pygame.draw.rect(game_window, green, [foodx, foody, snake_block_size, snake_block_size])
pygame.draw.rect(game_window, white, [x1, y1, snake_block_size, snake_block_size])
# 将当前贪吃蛇头的位置加入到贪吃蛇列表的第一个元素
snake_Head = [x1, y1]
snake_List.append(snake_Head)
# 如果贪吃蛇长度超过定义的初始值,移除贪吃蛇最后一个格子(除了头之外)
if len(snake_List) > Length_of_snake:
del snake_List[0]
# 判断是否撞到自己
for x in snake_List[:-1]:
if x == snake_Head:
game = False
break
# 更新食物位置和贪吃蛇长度
pygame.display.update()
if x1 == foodx and y1 == foody:
foodx = round(random.randrange(0, screen_width - snake_block_size) / 10.0) * 10.0
foody = round(random.randrange(0, screen_height - snake_block_size) / 10.0) * 10.0
Length_of_snake += 1
# 控制游戏帧率
clock = pygame.time.Clock()
clock.tick(30)
# 关闭游戏窗口并退出Pygame库
pygame.quit()
quit()
# 运行主函数
gameLoop()
auto_snake.py
import cv2
import pyautogui
# 打开摄像头
cap = cv2.VideoCapture(0)
# 初始化蛇的坐标和方向
prev_x = 0
prev_y = 0
while(True):
# 读取当前帧
ret, frame = cap.read()
# 对图像进行处理,识别蛇的位置和方向信息
frame_cropped = frame[0:500, 0:500]
frame_resized = cv2.resize(frame_cropped, (200, 200))
frame_gray = cv2.cvtColor(frame_resized, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(frame_gray, 50, 255, cv2.THRESH_BINARY)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
if len(contours) >= 1:
max_contour = max(contours, key=cv2.contourArea)
(x, y), radius = cv2.minEnclosingCircle(max_contour)
if radius > 5:
# 更新蛇的坐标
prev_x, prev_y = x, y
# 确定蛇的移动方向并模拟按键
if x < prev_x:
pyautogui.press('left')
elif x > prev_x:
pyautogui.press('right')
elif y < prev_y:
pyautogui.press('up')
elif y > prev_y:
pyautogui.press('down')
# 显示处理后的图像
cv2.imshow('frame', frame)
# 退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头和窗口
cap.release()
cv2.destroyAllWindows()
使用说明:
- 将两个 Python 文件保存到同一个文件夹中。
- 运行 snake_game.py,启动贪吃蛇游戏。
- 在游戏窗口打开后,运行 auto_snake.py。
注意:
- auto_snake.py 程序需要摄像头才能识别贪吃蛇。
- 自动控制程序的识别效果可能受光线、蛇的颜色等因素的影响。
- 由于 PyAutoGUI 库的限制,自动控制程序可能无法控制所有游戏中的按键。
代码改进方向:
- 使用更准确的图像识别算法,例如神经网络,提高自动控制程序的识别精度。
- 使用更稳定的控制方法,避免自动控制程序出现误操作。
- 将自动控制程序与贪吃蛇游戏代码整合到一起,方便使用。
- 添加游戏难度控制和游戏结束判断功能,使自动控制程序更具实用性。
本程序仅供学习和参考使用。
原文地址: http://www.cveoy.top/t/topic/nILc 著作权归作者所有。请勿转载和采集!