这让我发疯,我正在制作一个电路模拟程序,每当我问一个关于它的问题时,它就会被关闭。
我非常需要帮助,但是在任何人都可以帮我回答之前我的问题就会被关闭。
无论如何,这是问题所在: 实际上,我不知道问题是什么,这段代码有问题,我不知道它是什么?这一切看起来很好,我找不到任何错误,但它只是不起作用。
在这个程序中,有电线和电源,当我将电源放在电线旁边时,我希望它能够通电,并且所有连接的电线也都被供电,但这个程序显示出非常奇怪的行为除了我认为它会做的事情之外,还要做一切。当连接电源时,我希望电线亮起,当没有电源时,我想要电源禁用。当我放置电源时它们会亮起,但是当我放置更多电线时,它们都会被禁用,我似乎无法找出原因。
(深红色=黑色电源=未通电) 这是我在电源旁放置一根电线的时候:
然后我添加了更多内容:
以下是代码:
import pygame
from pygame.locals import *
pygame.init()
screen=pygame.display.set_mode((640,480))
blocks=[]
class PowerSource(object):
def __init__(self,pos):
self.posx=pos[0]
self.posy=pos[1]
self.rect=pygame.Rect(self.posx,self.posy,32,32)
self.powered=True
def update(self):
pygame.draw.rect(screen, (255,0,0), self.rect, 0)
def repos(self):
pass
class Circuit(object):
def __init__(self,pos):
self.powered=False
self.posx=pos[0]
self.posy=pos[1]
self.rect=pygame.Rect(self.posx,self.posy,32,32)
self.topped=False
self.lefted=False
self.righted=False
self.bottomed=False
def update(self):
self.powered=False
if any(b.rect.collidepoint(self.rect.left,self.rect.top-5) for b in [b for b in blocks if b is not self]):
if b.powered==True:
self.powered=True
if any(b.rect.collidepoint(self.rect.left,self.rect.top+38) for b in [b for b in blocks if b is not self]):
if b.powered==True:
self.powered=True
if any(b.rect.collidepoint(self.rect.left-5,self.rect.top) for b in [b for b in blocks if b is not self]):
if b.powered==True:
self.powered=True
if any(b.rect.collidepoint(self.rect.right+5,self.rect.top) for b in [b for b in blocks if b is not self]):
if b.powered==True:
self.powered=True
if not self.powered:
pygame.draw.rect(screen, (0,0,0), self.rect, 0)
else:
pygame.draw.rect(screen, (200,0,0), self.rect, 0)
while True:
place=1
screen.fill((255,255,255))
mse=pygame.mouse.get_pos()
mse=((mse[0]/32)*32,(mse[1]/32)*32)
pressed=pygame.mouse.get_pressed()
if pressed==(1,0,0):
pressed='L'
elif pressed==(0,0,1):
pressed='R'
for b in blocks:
b.update()
pygame.draw.rect(screen, (255,0,0), (mse[0],mse[1],32,32), 2)
for e in pygame.event.get():
if e.type==QUIT:
exit()
key=pygame.key.get_pressed()
if key[K_SPACE]:
for b in blocks:
if b.rect.collidepoint(mse):
place=0
if place==1:
blocks.append(PowerSource(mse))
if pressed=='L':
for b in blocks:
if b.rect.collidepoint(mse):
place=0
if place==1:
blocks.append(Circuit(mse))
elif pressed=='R':
for b in blocks:
if b.rect.collidepoint(mse):
blocks.remove(b)
pygame.display.flip()
拜托,请帮助我!我很沮丧。
答案 0 :(得分:2)
这里有几个问题。首先,眼前的问题。
在update
中,您认为b
来自哪一行?
if b.powered==True:
这不是来自其中一个部分:
if any(b.rect.collidepoint(self.rect.left,self.rect.top-5) for b in [b for b in blocks if b is not self]):
^ ^
它来自此列表理解的最后一次迭代:
[b for b in blocks if b is not self]
阻止列表中的最后一个非自身块用于所有if b.powered == True
测试。生成器表达式的循环变量在生成器表达式之外不可用,并且列表推导的循环变量仅在列表推导之外可用,因为出于性能原因而在Python 3中进行了设计决策。
不要尝试在b
调用之外使用any
,而是将测试置于其中:
if any(b.powered and b is not self and b.rect.collidepoint(self.rect.left,self.rect.top-5) for b in blocks):
或者因为这是一个相当大的行,将其拆分为显式循环而不是any
调用。当你在它时,你可以将4 any
个调用合并到列表中的一个传递中:
for b in blocks:
if not b.powered:
continue
if b is self:
# You don't actually need this test.
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(...):
adjacent = True
# and the other two adjacency checks
...
if adjacent:
self.powered = True
break
现在,其他问题。您的上电逻辑仅检查相邻块。这意味着如果一个块与电源分开然后连接,则可能需要对块进行许多更新才能实现它的接收功率。此外,如果一个块断电或电源被移除,该块可能永远不会关闭,因为无论何时,它的所有邻居都被供电。这将需要更改您的算法。我建议使用电源中的flood fill来确定哪些块已通电。