萝卜头IT论坛

了解更多
搜索
查看: 317|回复: 1
收起左侧

python实现吃满屏幕的贪吃蛇

[复制链接]
发表于 2020-3-14 23:29:58 | 显示全部楼层 |阅读模式
[md]```py
import pygame
from sys import exit
import random, math

pygame.init()
mapW = 300
mapH = 330
ROW = 11
COL = 10
# 0 * 0 ~ 29 * 19
# pixelSize = mapH / ROW
dirs = [[1,0],[0,1],[0,-1],[-1,0],[0,0]]
dirNow = 1
dirPause = 4
window = pygame.display.set_mode((mapW, mapH))
pygame.display.set_caption('Snack')

snack = [(ROW // 2, COL // 2)]
food = [(ROW - 1, COL - 1)]
colors = [(200, 147, 158), (0, 158, 128)]

def drawRect(pos, color):
    RecX = pos[1] * mapH / ROW
    RecY = pos[0] * mapW / COL
    pygame.draw.rect(window, color, (RecX, RecY, mapH / ROW, mapW / COL))

def ex(pos):
    if(pos[0] < 0 or pos[1] < 0 or pos[0] > ROW - 1 or pos[1] > COL - 1):
        return False
    return True

def gen_food():
    nEWFood = (random.randint(0, ROW - 1), random.randint(0, COL - 1))
    while(newFood in snack):
        newFood = (random.randint(0, ROW - 1), random.randint(0, COL - 1))
    food.append(newFood)

def bfs(st, ed, block):
    flag = False
    queue = [st]
    pre = [0]
    head = 0
    while(head < len(queue)):
        newNode = queue[head]
        head+=1
        rd = random.randint(0,3)
        for i in range(4):
            i = (i + rd) % 4
            ppos = (newNode[0] + dirs[0], newNode[1] + dirs[1])
            if not ex(ppos):
                continue
            if ppos == ed:
                queue.append(ppos)
                pre.append(head - 1)
                flag = True
                break
            if ppos in block:
                continue

            if ppos not in queue:
                queue.append(ppos)
                pre.append(head - 1)
        if flag:
            break
    res = []
    last = len(queue) - 1
    if flag :
        while last != pre[last]:
            res.append(queue[last])
            last = pre[last]
    return res[::-1]


def get_dir(pos1, pos2):
    for i in range(4):
        if((pos1[0] + dirs[0], pos1[1] + dirs[1]) == pos2):
            return i
    return 4

quitFlag = True
clock = pygame.time.Clock()
road = []
def finddir(snack):
    res = []
    for i in range(4):
        Node = (snack[0][0] + dirs[0], snack[0][1] + dirs[1])
        if Node in snack:
            continue
        if not ex(Node):
            continue
        if len(bfs(Node, snack[-2], [Node] + snack[:-2])) > 0:
            res.append(Node)
    if(len(res) <= 0):
        debug = 1
        return res
    ret = res[0]

    for i in res:
        if(abs(i[0] - food[0][0]) + abs(i[1] - food[0][1]) > abs(ret[0] - food[0][0]) + abs(ret[1] - food[0][1])):
            ret = i
    return [ret]
while quitFlag:
    clock.tick(60)
    # 获取事件,包括键盘事件和退出事件,也可防止卡死
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quitFlag = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                t = dirPause
                dirPause = t
                dirNow = dirPause

    if len(road) == 0:
        nextPath = bfs(snack[0], food[0], snack)
        findTail = bfs(snack[0], snack[-1], snack)
        if len(nextPath) > 0:
            if(len(nextPath) > len(snack)):
                findTail2 = bfs(nextPath[-1], nextPath[-len(snack) - 1], nextPath[-1:-len(snack) - 2])
            else:
                findTail2 = bfs(nextPath[-1], snack[len(snack) - len(nextPath)], nextPath + snack[0:len(snack) - len(nextPath)])
            if len(findTail2) > 0:
                road = nextPath
            else:
                road = finddir(snack)
        else :
            road = finddir(snack)
        if len(road) == 0:
            road = findTail
    nextRec = road[0]
    road.pop(0)
    if ex(nextRec):
        if(nextRec not in food):
            snack.pop()
        else :
            food.pop()
            gen_food()
        snack.insert(0, nextRec)
    else:
        print("Game over at %d %d"%(nextRec[0],nextRec[1]))
        quitFlag = False

    pygame.draw.rect(window, (245, 135, 155), (0, 0, mapW, mapH))
    for body in snack:
        drawRect(body, colors[0])
    drawRect(snack[0], (255,255,255))
    for body in food:
        drawRect(body, colors[1])
    pygame.display.flip()


```
![snk.png](data/attachment/forum/202003/14/232951n88duf9eeex9biui.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600 "snk.png")

效果


[/md]
SG]FZ}I~T1OPYFI{P28]_T3.png
snk.png
回复

使用道具 举报

发表于 2020-3-15 09:42:13 | 显示全部楼层
收藏!
回复

使用道具 举报

联系站长(Contact)|萝卜头IT论坛 ( 苏ICP备15050961号-1 )

GMT+8, 2020-8-7 20:17 , Processed in 0.084334 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

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