I've been working a circuit simulator, kind of like Minecraft's red-stone, but in 2d.
So far, I have power sources and wires. The power sources give power to the wire, which will later be used to power other components.
The problem I am facing is when the wire is disconnected from the source, it stays powered, because all of it's neighbors are powered.
Here is the issue represented in images:
Wire not connected to power
Wire is connected, and powered
Power removed, but wire is still active
Here is the update loop from the wire showing this:
def update(self):
self.powered=False
for b in blocks:
#Find power sources/powered wires
if not b.powered:
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(self.rect.left,self.rect.bottom+5):
adjacent = True
if b.rect.collidepoint(self.rect.left-5,self.rect.top):
adjacent = True
if b.rect.collidepoint(self.rect.right+5,self.rect.top):
adjacent = True
if adjacent:
self.powered = True
break
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)
I need the wires to be powered by other wires, but only if they are all connected to a source.. so I figured, if I can have each wire segment recursively check all the ones that it is connected to, to make sure it is connected to a power source, then I could achieve this. But I am not sure how to do this.
I tried using other variables inside of the wire object like self.sourced
which represented if the wire was connected to a power source, but this resulted in only being able top power one wire. (even though when the power source was broken, the wire deactivated, so it kind of worked..)
Anyways, if anyone has know how to do this, please lend me your knowledge.
Here is the full source-code for reference:
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)
def update(self):
self.powered=False
for b in blocks:
if not b.powered:
continue
adjacent = False
if b.rect.collidepoint(self.rect.left,self.rect.top-5):
adjacent = True
if b.rect.collidepoint(self.rect.left,self.rect.bottom+5):
adjacent = True
if b.rect.collidepoint(self.rect.left-5,self.rect.top):
adjacent = True
if b.rect.collidepoint(self.rect.right+5,self.rect.top):
adjacent = True
if adjacent:
self.powered = True
break
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()