为什么我的支票命中方法说它是安全的,而不是(蛇)?

2024-05-16 20:48:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我用pygame做了一个程序,由多条蛇同时运行,长度不断增加。在这个类中,我有一个类playerUpdates,在这个类中,应该有人创建一个方法,返回他们希望蛇朝哪个方向走。我的问题是,这里的函数名为“Person2” 在它里面,我在“Person1”中使用几乎完全相同的方法来检查它是否会被击中,但是如果你运行它,你会看到一段时间后,它说它是安全的,并返回一个方向,然后杀死它。我不明白为什么会这样,因为我做了整个程序,所以我觉得我应该知道什么会杀死它或不。我已经花了好几个小时想弄明白这一点,但似乎什么都不管用

代码如下:

#SnakeVsRoyale.py
import pygame
import os
import math
from random import randint
from pygame.locals import *
import time

pygame.init()

width = 800
height = 500
size = 10
win = pygame.display.set_mode((width,height))
pygame.display.set_caption("Snake Royale")

PATH = os.path.abspath(__file__)
PATH = PATH[0:-16] #-16 to chop off SnakeVsRoyale.py
font = pygame.font.SysFont('', 24)
bigFont = pygame.font.SysFont('', 30)

clock = pygame.time.Clock()

length = 1

class Snake:
    global length
    def __init__(self, pos, dir, name):
        self.bod = [pos] #Lists [[x,y], [x,y]...]
        self.dir = dir #String 'direction'
        self.pos = pos.copy() #List [x,y]
        self.name = name #Name 'Chris'
        self.length = 1
        self.kills = 0
        self.alive = True
        self.color = (randint(100,255),randint(100,255),randint(100,255)) #Start at 100 so it's not black or dark
    def getInfo(self):
        return [self.bod.copy(), self.dir, self.pos.copy()]
    def getEndInfo(self):
        return [self.name, self.length, self.kills]
    def setDir(self, info):
        self.dir = getattr(playerUpdates, self.name)(self.pos.copy(), self.bod.copy(), self.dir, info.copy())
    def update(self, win):
        if self.alive:
            if self.dir == 'right':
                self.pos[0]+=size
            elif self.dir == 'left':
                self.pos[0]-=size
            elif self.dir == 'up':
                self.pos[1]-=size
            elif self.dir == 'down':
                self.pos[1]+=size
            else:
                print("No direction set", self.name)
            self.bod.append([self.pos[0], self.pos[1]])
            if len(self.bod) > length: #length is global, self.length is the class variable
                self.bod.pop(0)
        if self.alive:
            for i in self.bod:
                pygame.draw.rect(win, self.color, pygame.Rect(i[0], i[1], size, size))
            pygame.draw.rect(win, (255,255,255), pygame.Rect(self.pos[0], self.pos[1], size, size))
            nameText = font.render(self.name, True, (100,100,100))
            loc = nameText.get_rect()
            loc.center = (self.pos[0]+10, self.pos[1]-14)
            w, h = loc.size
            pygame.draw.rect(win, (255,255,255), pygame.Rect(loc.x, loc.y, w, h))
            win.blit(nameText, loc)
        else:
            self.bod = []
            self.pos =[-100,-100]

def main():
    global length
    players = ['Person1', 'Person2']
    snakeList = []
    info = []
    tickRate = 5
    feed = []

    dirs = ['right', 'left', 'up', 'down']
    for i in players:
        snake = Snake([randint(1,(width/size)-2)*size, randint(1,(height/size)-2)*size], dirs[randint(0,3)], i)
        snakeList.append(snake)

    end = True
    playing = True
    tStart = time.time()
    while playing:
        clock.tick(tickRate)
        for event in pygame.event.get():
            if event.type == QUIT:
                playing = False
                end = False

        info = []
        for i in snakeList:
            info.append(i.getInfo())
        for i in snakeList:
            i.setDir(info.copy())
        #Check hit
        for i in snakeList:
            if i.alive:
                inf = i.getInfo()
                loc = inf[2]
                for x in info:
                    if loc in x[0]:
                        if inf[0]==x[0]: #Checks if it is itself
                            temp = x[0].copy()
                            temp.remove(loc)
                            if loc in temp: #Checks to see if the value is in the list twice
                                i.alive = False
                                snakeList.remove(i)
                                feed.append([i.name+' is out (Hit itself)', 0])
                        else: #Makes sure it isn't current position
                            i.alive = False
                            snakeList.remove(i)
                            feed.append([i.name+' is out (Hit Snake)', 0])
                if loc[0] < 0 or loc[0]>=width or loc[1]<0 or loc[1]>=height:
                    i.alive = False
                    snakeList.remove(i)
                    feed.append([i.name+' is out (Border)', 0])
        if (time.time()-tStart) > 1:
            length += 1
            tStart = time.time()
        if length > 3:
            tickRate = 10

        keys = pygame.key.get_pressed()
        for i in keys:
            if i:
                end = False
                playing = False

        #Draw everything
        pygame.draw.rect(win, (0,0,0), pygame.Rect(0,0,width,height)) #black background
        for i in snakeList:
            i.update(win)
        ycounter = 20
        for i in feed:
            text = bigFont.render(i[0], True, (0,0,0))
            loc = text.get_rect()
            loc.topleft = (20,ycounter)
            w, h = loc.size
            pygame.draw.rect(win, (255,255,255), pygame.Rect(loc.x-5, loc.y-5, w+10, h+10))
            win.blit(text, loc)
            ycounter+=h+15
            i[1] += 2
            if i[1] > 200:
                feed.remove(i)
        pygame.draw.rect(win, (255,255,255), pygame.Rect(0,0,width,height), 1) #White border
        pygame.display.update()

    while end: #This doesn't do anything I think
        clock.tick(tickRate)
        for event in pygame.event.get():
            if event.type == QUIT:
                end = False
        #Draw everything
        pygame.draw.rect(win, (0,0,0), pygame.Rect(0,0,width,height)) #Background


        pygame.display.update()
    pygame.quit()

class playerUpdates:
    #pos is [x,y] bod is [[x,y],[x,y]...]
    #info is [[bod, dir, pos], [bod, dir, pos]...]
    def Person1(pos, bod, dir, info):
        def getDirs(bod):
            dirs = []
            newBod = []
            for i in range(len(bod)-1, len(bod)-12,-1):
                newBod.append(bod[i])
            for i in range(0,len(newBod)-2):
                if newBod[i][0] == newBod[i+1][0]:
                    if newBod[i][1] > newBod[i+1][1]:
                        dirs.append('down')
                    else:
                        dirs.append('up')
                else:
                    if newBod[i][0] > newBod[i+1][0]:
                        dirs.append('right')
                    else:
                        dirs.append('left')
            return dirs
        def hit(dirr, info, bod, pos):
            newX, newY = pos[0], pos[1]
            if dirr == 'right':
                newX += size
            if dirr == 'left':
                newX -= size
            if dirr == 'up':
                newY -= size
            if dirr == 'down':
                newY += size
            if newX >= width or newX < 0 or newY >= height or newY <= 0: #Attempts to leave a section open on border
                return True
            for i in info:
                badX, badY = i[2][0], i[2][1]
                if i[1] == 'right':
                    badX += size
                if i[1] == 'left':
                    badX -= size
                if i[1] == 'up':
                    badY -= size
                if i[1] == 'down':
                    badY += size

                if [newX, newY] in i[0]:
                        return True
                if [newX, newY] == [badX, badY]:
                    if bod == i[0]:
                        pass
                    else:
                        return True
            return False

        if (len(bod) > 6):
            dirs = getDirs(bod) #pos 0 is the most recent
            if (dirs[0] == dirs[1] and dirs[0] == 'up') or (dirs[1] == dirs[2] and dirs[1] == 'up'):
                if dirs[0] == dirs[1] and dirs[0] == 'up':
                    if dirs[2] == 'left':
                        if not(hit('right', info, bod, pos)):
                            return 'right'
                    elif dirs[2] == 'right':
                        if not(hit('left', info, bod, pos)):
                            return 'left'
                if dirs[0] == 'up' and not(dirs[1] == 'up'):
                    if not(hit('up', info, bod, pos)):
                        return 'up'
                if dirs[0] == 'left' or dirs[0] == 'right' and pos[0] > 10*size and pos[0] < width-10*size:
                    if not(hit('up',info, bod, pos)):
                        return 'up'

        if pos[1] > height-5*size and pos[0] > randint(15,30)*size and pos[0] < width-randint(12,30)*size:
            if not(hit('up', info, bod, pos)):
                return 'up'
        if not(hit(dir, info, bod, pos)): #and not(randint(0,20)==1):
            return dir
        else:
            lr = ['left', 'right']
            temp = lr.pop(randint(0,1))
            if not(hit(temp, info, bod, pos)):
                return temp
            elif not(hit(lr[0], info, bod, pos)):
                return lr[0]
            elif not(hit('down', info, bod, pos)):
                return 'down'
            elif not(hit('up', info, bod, pos)):
                return 'up'
            '''
            dirs = ['right', 'left', 'up', 'down']
            for i in range(0,4):
                newDir = dirs.pop(randint(0,len(dirs)-1))
                if not(hit(newDir, info, bod, pos)):
                    return newDir
            return dir
            '''
        return dir
    def Person(pos, bod, dir, info):
        def hit(dirr, info, bod, pos):
            if randint(0,20) == 1:
                return True
            newX, newY = pos[0], pos[1]
            if dirr == 'right':
                newX += size
            if dirr == 'left':
                newX -= size
            if dirr == 'up':
                newY -= size
            if dirr == 'down':
                newY += size
            if newX >= width or newX < 0 or newY >= height or newY < 0:
                return True
            for i in info:
                badX, badY = i[2][0], i[2][1]
                if i[1] == 'right':
                    badX += size
                if i[1] == 'left':
                    badX -= size
                if i[1] == 'up':
                    badY -= size
                if i[1] == 'down':
                    badY += size

                if [newX, newY] in i[0]:
                        return True
                if [newX, newY] == [badX, badY]:
                    if bod == i[0]:
                        pass
                    else:
                        return True
            return False
        if not(hit(dir, info, bod, pos)):
            return dir
        else:
            dirs = ['right', 'left', 'up', 'down']
            for i in range(0,4):
                newDir = dirs.pop(randint(0,len(dirs)-1))
                if not(hit(newDir, info, bod, pos)):
                    return newDir
            return dir

        newX, newY = pos[0], pos[1]
        if dir == 'right':
            newX += size
        if dir == 'left':
            newX -= size
        if dir == 'up':
            newY -= size
        if dir == 'down':
            newY += size

        if newX >= width:
            return 'up'
        if newX < 0:
            return 'down'
        if newY >= height:
            return 'right'
        if newY < 0:
            return 'left'
        return dir
    def Person2(pos, bod, dir, info):
        print('--------------------------------------')
        def hit(pos, bod, dirr, info):
            newX, newY = pos[0], pos[1]
            if dirr == 'right':
                newX += size
            if dirr == 'left':
                newX -= size
            if dirr == 'up':
                newY -= size
            if dirr == 'down':
                newY += size
            if newX >= width or newX < 0 or newY >= height or newY < 0:
                print('not safe')
                return True
            for i in info:
                if [newX, newY] in i[0]:
                        print('not safe')
                        return True
                else:
                    print(i[0])
                    print(pos)
                    print(newX, newY)
            print('safe')
            return False

        if len(bod) > 3:
            if pos[0] < bod[0][0] and not(hit(pos, bod, 'right', info)):
                print('Moving right to follow')
                return 'right'
            if pos[0] > bod[0][0] and not(hit(pos, bod, 'left', info)):
                print('Moving left to follow')
                return 'left'
            if pos[1] < bod[0][1] and not(hit(pos, bod, 'down', info)):
                print('Moving down to follow')
                return 'down'
            if pos[1] > bod[0][1] and not(hit(pos, bod, 'up', info)):
                print('Moving up to follow')
                return 'up'

        if len(bod) <= 3:
            print('length', len(bod))
            if dir == 'up':
                print(1)
                return 'right'
            if dir == 'right':
                print(2)
                return 'down'
            if dir == 'down':
                print(3)
                return 'left'
            if dir == 'left':
                print(4)
                return 'up'
        print('didnt follow')
        if not(hit(pos, bod, 'up', info)):
            print('up')
            return 'up'
        if not(hit(pos, bod, 'down', info)):
            print('down')
            return 'down'
        if not(hit(pos, bod, 'left', info)):
            print('left')
            return 'left'
        if not(hit(pos, bod, 'right', info)):
            print('right')
            return 'right'
        print('im dead')
        return dir

main()

Tags: posselfrightinfosizereturnifdir