Skip to content

Instantly share code, notes, and snippets.

@mousetail
Created November 23, 2016 14:51
Show Gist options
  • Save mousetail/8a0e91d794d7167e02f5b92048849f04 to your computer and use it in GitHub Desktop.
Save mousetail/8a0e91d794d7167e02f5b92048849f04 to your computer and use it in GitHub Desktop.
#2d_anim.py
#Maurits van Riezen (mousetail)
#23 November 2015
#Requires python 3 and pygame for python 3
import pygame
import random
import itertools
import os
class Item(object):
def __init__(self, position):
self.color=random.choice(((0, 0, 0),(255,255,255)))
self.borderColor=tuple(255-i for i in self.color)
self.circle=random.choice((True,False))
self.position=list(position) #Position is used for external reference only, it is not ever used
def draw(self, surface, position):
if self.circle:
pygame.draw.circle(surface, self.color, position, 8, 0)
pygame.draw.circle(surface, self.borderColor, position, 8, 2)
else:
pygame.draw.rect(surface, self.color, (position[0]-8,position[1]-8,16,16))
pygame.draw.rect(surface, self.borderColor, (position[0]-8,position[1]-8,16,16), 2)
class Game(object):
WIDTH=8
HEIGHT=6
SPEED=180
def __init__(self):
self.screen=pygame.display.set_mode((128*self.WIDTH, self.HEIGHT*128))
self.generate()
self.drawGUI=True
self.holeIndex=0
self.recording=False
self.draw()
self.check()
for iteration in range(4):
for i in range(len(self.machines)):
for j in range(len(self.machines[i])):
if random.randint(0,2)==1:
done=False
for x in range(-1,2):
for y in range(-1, 2):
if ((x==0) ^ (y==0)) and self.machines[i][j].__class__.getInputSides(x,y):
self.machines[i][j].addItem(Item((0,64)),(x, y))
done=True
break
if done:
break
for i in range(random.randint(12,48)):
self.update()
def generate(self):
mainClasses=[]
midClasses=[]
junkClasses=[]
self.whiteHoles=[]
mainClasses.append(splitterMerger(((-1,0),(1,0)),((0,-1),(0,1))))
mainClasses.append(splitterMerger(((0,-1),(0,1)),((-1,0),(1,0))))
x=0
y=1
for direct in range(4):
directions=((x,y),(y,-x),(-x,-y),(-y,x))
gr=(random.choice((mainClasses,midClasses,midClasses,midClasses)) for i in range(3))
next(gr).append(bend(directions[0],directions[1]))
next(gr).append(bend(directions[1], directions[0]))
next(gr).append(bend(directions[0], directions[2]))
for i in range(-1,2):
for j in range(-1,2):
for k in range(-1,2):
if (j>i and k>i and k>=j):
if (j!=k):
l=merger((directions[i],directions[j],directions[k]),
directions[2])
l2=splitter((directions[i],directions[j],directions[k]),
directions[2])
else:
l=merger((directions[i],directions[k]),directions[2])
l2=splitter((directions[i],directions[k]),directions[2])
if j==k and random.randint(0,10)==1:
mainClasses.append(l2)
mainClasses.append(l)
else:
midClasses.append(l2)
midClasses.append(l)
midClasses.append(crosser(directions[0],directions[1],directions[3],directions[2]))
if direct==1 or direct==2:
midClasses.append(crosser(directions[0],directions[1],directions[2],
directions[3]))
x, y=directions[1]
for i in range(2):
for j in range(2):
for k in range(2):
for l in range(2):
dirs=(0,1),(1,0),(-1,0),(0,-1)
if (i or j or k or l):
junkClasses.append(whiteHole(tuple(dirs[m] for m in range(4) if (i,j,k,l)[m])))
junkClasses.append(blackHole(tuple(dirs[m] for m in range(4) if (i,j,k,l)[m])))
self.machines=[]
for i in range(self.WIDTH):
self.machines.append([None,]*self.HEIGHT)
for i in range(30):
x=random.randint(0,len(self.machines)-1)
y=random.randint(0,len(self.machines[x])-1)
if self.machines[x][y] is None:
self.machines[x][y]=self.findMachine(x,y,mainClasses,30)
for x in range(len(self.machines)):
for y in range(len(self.machines[0])):
if (self.machines[x][y] is None):
self.machines[x][y]=self.findMachine(x,y,mainClasses,30)
#if self.machines[x][y]!=None: print ("first try",(x,y))
if (self.machines[x][y] is None):
self.machines[x][y]=self.findMachine(x,y,midClasses,480)
#if self.machines[x][y]!=None: print ("second try",(x,y))
if (self.machines[x][y] is None):
self.machines[x][y]=self.findMachine(x,y,mainClasses,400)
#if self.machines[x][y]!=None: print ("third try",(x,y))
if self.machines[x][y] is None:
self.machines[x][y]=self.findMachine(x,y,junkClasses,660)
#if self.machines[x][y]!=None: print ("fourth try",(x,y))
if self.machines[x][y] is None:
#print ("giving up",(x,y))
self.machines[x][y]=junkClasses[-1]()
if self.machines[x][y].getInputSides(0,0):
self.whiteHoles.append(self.machines[x][y])
#print (x,y,self.machines[x][y])
def findMachine(self, x, y, group, numiterations=60):
dirs=(0,1),(1,0),(0,-1),(-1,0)
for i in range(numiterations):
machine=random.choice(group)
done=True
for k in range(4):
oldMachine=self.getMachineAt((x,y),dirs[k])
if oldMachine is None:
pass
elif ((machine.getOutputSides(*dirs[k]) and not oldMachine.getInputSides(*dirs[k-2])) or
(machine.getInputSides(*dirs[k]) and not oldMachine.getOutputSides(*dirs[k-2])) or
(oldMachine.getOutputSides(*dirs[k-2]) and not machine.getInputSides(*dirs[k])) or
(oldMachine.getInputSides(*dirs[k-2]) and not machine.getOutputSides(*dirs[k]))):
done=False
done=False
if done:
for dx, dy in dirs:
if self.getMachineAt((x,y),(dx,dy)) is None:
pass
elif machine.getOutputSides(dx,dy):\
assert self.getMachineAt((x,y),(dx,dy)).getInputSides(-dx,-dy), str((x,y))+str((dx,dy))
elif machine.getInputSides(dx,dy):
assert self.getMachineAt((x,y),(dx,dy)).getOutputSides(-dx,-dy), str((x,y))+str((dx,dy))
elif not machine.getInputSides(dx, dy) and not machine.getInputSides(dx, dy):
assert (not self.getMachineAt((x,y),(dx,dy)).getOutputSides(-dx,-dy) and
not self.getMachineAt((x,y),(dx,dy)).getInputSides(-dx,-dy)), str((x,y))+str((dx,dy))
#print ("took",i,"iterations ",(x,y))
return machine()
return None
def check(self):
dirs=(0,1),(1,0),(0,-1),(-1,0)
for x, i in enumerate(self.machines):
for y, j in enumerate(i):
assert self.getMachineAt((x,y),(0,0))!=None, str(x,y)
for dx, dy in dirs:
if self.getMachineAt((x,y),(0,0)).getOutputSides(dx,dy):
assert self.getMachineAt((x,y),(dx,dy)).getInputSides(-dx,-dy), str((x,y))+str((dx,dy))
if self.getMachineAt((x,y),(0,0)).getInputSides(dx,dy):
assert self.getMachineAt((x,y),(dx,dy)).getOutputSides(-dx,-dy), str((x,y))+str((dx,dy))
def getMachineAt(self, pos, rel=(0,0)):
return self.machines[(pos[0]+rel[0])%len(self.machines)][(pos[1]+rel[1])%len(self.machines[0])]
def update(self):
items=[]
for x, column in enumerate(self.machines):
for y, machine in enumerate(column):
items.extend((x+dx,y+dy, (-dx, -dy), item) for ((dx, dy), item) in machine.update())
for x, y, direction, item in items:
if direction!=(0,0):
self.getMachineAt((x,y),(0,0)).addItem(item, direction)
else:
self.holeIndex+=1
if self.holeIndex>=len(self.whiteHoles):
self.holeIndex=0
if len(self.whiteHoles)>0:
self.whiteHoles[self.holeIndex].addItem(item, direction)
def draw(self):
self.screen.fill((0,0,0))
if self.drawGUI:
for x, i in enumerate(self.machines):
for y, j in enumerate(i):
j.drawBack(self.screen, (128*x, 128*y))
for x, i in enumerate(self.machines):
for y, j in enumerate(i):
j.draw(self.screen, (128*x, 128*y))
pygame.display.flip()
def event(self):
for event in pygame.event.get():
if event.type==pygame.QUIT:
self.running=False
elif event.type==pygame.KEYDOWN:
if event.key==pygame.K_g:
self.drawGUI=not self.drawGUI
elif event.key==pygame.K_r:
if self.recording:
self.stopRecording()
else:
self.startRecording()
#print ("QUIT")
def run(self):
clock=pygame.time.Clock()
self.running=True
while self.running:
clock.tick(self.SPEED)
self.update()
self.draw()
if self.recording:
self.record()
self.event()
def startRecording(self):
index=0
while os.path.exists(str(index)):
index+=1
os.mkdir(str(index))
self.recorddir=str(index)
self.recording=True
self.framenumber=0
def record(self):
if framenumber%2==0:
pygame.image.save(self.screen, self.recorddir+"/"+str(self.framenumber)+".png")
self.framenumber+=1
def stopRecording(self):
self.recording=False
class Machine(object):
@staticmethod
def getInputSides(xoffset, yoffset):
return False
@staticmethod
def getOutputSides(xoffset, yoffset):
return False
######
#There are a total of 81 combinations:
#so far, I have
# 1 straigt (/4) | 1-1
# 8 bends (out of 8) | 1-1
#16 mergers | 3-1 2-1
#16 splitters | 1-3 1-2
#I need:
# 6 crossings | 2-2
#16 black holes | 1-0 2-0 3-0 4-0
#16 white holes | 0-1 0-2 0-3 0-4
class ConveyorBelt(Machine):
@staticmethod
def getInputSides(xoffset, yoffset):
return yoffset==0 and xoffset==-1
@staticmethod
def getOutputSides(xoffset, yoffset):
return yoffset==0 and xoffset==1
def __init__(self):
self.items=[]
def update(self):
out=[]
for i in self.items:
i.position[0]+=1
if i.position[0]>128:
out.append(i)
return (self.items.remove(i) or ((1,0),i) for i in out)
def addItem(self, item, direction):
if direction==(-1,0):
self.items.append(item)
item.position[0]=0
item.position[1]=64
else:
raise ValueError(direction)
def draw(self, surface, position):
for i in self.items:
assert -64<=i.position[0]<=64 and -64<=i.position[1]<=64, "position is "+str(i.position)
i.draw(surface, (position[0]+i.position[0], position[1]+i.position[1]))
def bend(inSide, outSide):
class ActualBend(Machine):
@staticmethod
def getInputSides(xoffset, yoffset):
return xoffset==inSide[0] and yoffset==inSide[1]
@staticmethod
def getOutputSides(xoffset, yoffset):
return xoffset==outSide[0] and yoffset==outSide[1]
def __init__(self):
self.items=[]
def update(self):
out=[]
for i in self.items:
if ((inSide[0]!=0 and i.position[0]//inSide[0]>0) or
inSide[1]!=0 and i.position[1]//inSide[1]>0):
i.position[0]-=inSide[0]
i.position[1]-=inSide[1]
else:
i.position[0]+=outSide[0]
i.position[1]+=outSide[1]
if (outSide[0]!=0 and i.position[0]//outSide[0]==64) or (outSide[1]!=0 and i.position[1]//outSide[1]==64):
out.append(i)
return (self.items.remove(i) or (outSide,i) for i in out)
def addItem(self, item, direction):
self.items.append(item)
if inSide[0]!=0:
item.position[0]=inSide[0]*64
item.position[1]=0
elif inSide[1]!=0:
item.position[1]=inSide[1]*64
item.position[0]=0
def drawBack(self, surface, position):
pygame.draw.lines(surface, (0,0,0), 0, ((position[0]+64+inSide[0]*64, position[1]+64+inSide[1]*64),
(position[0]+64, position[1]+64),
(position[0]+64+outSide[0]*64, position[1]+64+outSide[1]*64)),4)
pygame.draw.lines(surface, (255,255,255), 0, ((position[0]+64+inSide[0]*64, position[1]+64+inSide[1]*64),
(position[0]+64, position[1]+64),
(position[0]+64+outSide[0]*64, position[1]+64+outSide[1]*64)))
def draw(self, surface, position):
for i in self.items:
assert -64<=i.position[0]<=64 and -64<=i.position[1]<=64, "position is "+str(i.position)
i.draw(surface, (position[0]+i.position[0]+64, position[1]+i.position[1]+64))
return ActualBend
def merger(entrances, exit):
class ActualMerger(Machine):
@staticmethod
def getInputSides(xoffset, yoffset):
for entrance in entrances:
if (xoffset==entrance[0] and yoffset==entrance[1]) :
return True
return False
@staticmethod
def getOutputSides(xoffset, yoffset):
return xoffset==exit[0] and yoffset==exit[1]
def __init__(self):
self.quiers=tuple((i,[]) for i in entrances)
self.exitquier=[]
self.quirpos=0
def update(self):
out=[]
for item in self.exitquier:
if (item.position[0]==0 and exit[0]==0):
item.position[1]+=exit[1]
elif (item.position[1]==0 and exit[1]==0):
item.position[0]+=exit[0]
elif (item.position[0]<0 and exit[0]==0):
item.position[0]+=1
elif (item.position[0]>0 and exit[0]==0):
item.position[0]-=1
elif (item.position[1]<0 and exit[1]==0):
item.position[1]+=1
elif (item.position[1]>0 and exit[1]==0):
item.position[1]-=1
if abs(item.position[0])==64 or abs(item.position[1])==64:
out.append(item)
assert abs(item.position[0]<=64) and abs(item.position[1])<=64, item.position
if (len(self.exitquier)==0 or
(exit[0]!=0 and abs(self.exitquier[-1].position[0])>=16) or
(exit[1]!=0 and abs(self.exitquier[-1].position[1])>=16)):
startf=self.quirpos
self.quirpos+=1
if self.quirpos>=len(self.quiers):
self.quirpos=0
f=self.quiers[self.quirpos]
while startf!=self.quirpos and (len(f[1])==0 or abs(f[1][0].position[0])>16 or abs(f[1][0].position[1])>16):
self.quirpos+=1
if self.quirpos>=len(self.quiers):
self.quirpos=0
f=self.quiers[self.quirpos]
if len(f[1])!=0:
item=f[1][0]
if (abs(item.position[0])<=16 and abs(item.position[1])<=16):
self.exitquier.append(f[1].pop(0))
for key, value in self.quiers:
for index, item in enumerate(value):
if ((index!=0 and (abs(item.position[0]-value[index-1].position[0]+item.position[1]-value[index-1].position[1])>16)) or
(index==0)) and (abs(item.position[0])>=16 or abs(item.position[1])>=16):
item.position[0]-=key[0]
item.position[1]-=key[1]
assert abs(item.position[0]<=64) and abs(item.position[1])<=64, item.position
return (self.exitquier.remove(i) or (exit, i) for i in out)
def addItem(self, item, direction):
self.quiers[entrances.index(tuple(direction))][1].append(item)
item.position[0]=direction[0]*64
item.position[1]=direction[1]*64
assert abs(item.position[0]<=64) and abs(item.position[1])<=64
def drawBack(self, surface, position):
pygame.draw.line(surface, (100,0,0), (position[0]+64, position[1]+64),
(position[0]+64+64*exit[0], position[1]+64+64*exit[1]),3)
for i in entrances:
pygame.draw.line(surface, (100,0,0), (position[0]+64, position[1]+64),
(position[0]+64+64*i[0], position[1]+64+64*i[1]))
def draw(self, surface, position):
for i in itertools.chain(self.exitquier, *(item for key, item in self.quiers)):
assert -64<=i.position[0]<=64 and -64<=i.position[1]<=64, "position is "+str(i.position)
i.draw(surface, (position[0]+i.position[0]+64, position[1]+i.position[1]+64))
return ActualMerger
def splitter(exits, entrance):
assert (entrance[0]==0) ^ (entrance[1]==0)
class ActualSplitter(Machine):
@staticmethod
def getOutputSides(xoffset, yoffset):
for exit in exits:
if (xoffset==exit[0] and yoffset==exit[1]) :
return True
return False
@staticmethod
def getInputSides(xoffset, yoffset):
return xoffset==entrance[0] and yoffset==entrance[1]
def __init__(self):
self.quiers=[(i,[]) for i in exits]
self.entrancequier=[]
self.currentQuirePos=0
def update(self):
out=[]
toremove=[]
for item in self.entrancequier:
item.position[0]-=entrance[0]
item.position[1]-=entrance[1]
assert -64<=item.position[0]<=64 and -64<=item.position[1]<=64, "position is "+str(item.position)
if item.position[0]==0 and item.position[1]==0:
self.quiers[self.currentQuirePos][1].append(item)
toremove.append(item)
self.currentQuirePos+=1
if self.currentQuirePos>=len(self.quiers):
self.currentQuirePos=0
for i in toremove:
self.entrancequier.remove(i)
for key, value in self.quiers:
for index, item in enumerate(value):
item.position[0]+=key[0]
item.position[1]+=key[1]
assert -64<=item.position[0]<=64 and -64<=item.position[1]<=64, "position is "+str(item.position)+" key is "+str(key)
if abs(item.position[0])==64 or abs(item.position[1])==64:
out.append((key, item))
for key, value in out:
suc=False
for i in self.quiers:
if i[0]==key:
i[1].remove(value)
suc=True
break
if not suc:
print ("Can't find quire to remove "+str(value)+" from")
return out
def addItem(self, item, direction):
assert direction[0]==entrance[0] and direction[1]==entrance[1], "direction="+str(direction)+"output="+str(entrance)
self.entrancequier.append(item)
item.position[0]=entrance[0]*64
item.position[1]=entrance[1]*64
def drawBack(self, surface, position):
pygame.draw.line(surface, (255,0,0), (position[0]+64, position[1]+64),
(position[0]+64+64*entrance[0], position[1]+64+64*entrance[1]),3)
for i in exits:
pygame.draw.line(surface, (255,0,0), (position[0]+64, position[1]+64),
(position[0]+64+64*i[0], position[1]+64+64*i[1]))
def draw(self, surface, position):
for i in itertools.chain(self.entrancequier, *(i[1] for i in self.quiers)):
assert -64<=i.position[0]<=64 and -64<=i.position[1]<=64, "position is "+str(i.position)
i.draw(surface, (position[0]+i.position[0]+64, position[1]+i.position[1]+64))
return ActualSplitter
def splitterMerger(ins, outs):
class ActualSplitterMerger(Machine):
def __init__(self):
self.input=[[],[]]
self.output=[[],[]]
self.limbo=None
self.limbodir=None
self.inIndex=0
self.outIndex=0
@staticmethod
def getOutputSides(xoffset, yoffset):
for exit in outs:
if (xoffset==exit[0] and yoffset==exit[1]) :
return True
return False
@staticmethod
def getInputSides(xoffset, yoffset):
for entrance in ins:
if (xoffset==entrance[0] and yoffset==entrance[1]):
return True
return False
def update(self):
out=[]
for dir, lis in enumerate(self.output):
toRemove=[]
for itm in lis:
itm.position[0]+=outs[dir][0]
itm.position[1]+=outs[dir][1]
if abs(itm.position[0])==64 or abs(itm.position[1])==64:
out.append((outs[dir], itm))
toRemove.append(itm)
for i in toRemove:
lis.remove(i)
if self.limbo is None:
start=self.inIndex
self.incrementInIndex()
while (self.inIndex!=start and (len(self.input[self.inIndex])==0 or
(abs(self.input[self.inIndex][0].position[0])!=16
and abs(self.input[self.inIndex][0].position[1])!=16))):
self.incrementInIndex()
if (len(self.input[self.inIndex])>0 and
((abs(self.input[self.inIndex][0].position[0])==16 or
abs(self.input[self.inIndex][0].position[1])==16))):
self.limbo=self.input[self.inIndex][0]
self.input[self.inIndex].pop(0)
self.incrementOutIndex()
self.limbodir=tuple(outs[self.outIndex][i]-ins[self.inIndex][i] for i in (0,1))
if self.limbo is not None:
self.limbo.position[0]+=self.limbodir[0]
self.limbo.position[1]+=self.limbodir[1]
if ((abs(self.limbo.position[0])==16 or abs(self.limbo.position[1])==16)):
self.output[self.outIndex].append(self.limbo)
self.limbo=None
for dir, lst in enumerate(self.input):
for index, itm in enumerate(lst):
if (index==0 or abs(lst[index-1].position[0]-itm.position[0])>16
or abs(lst[index-1].position[1]-itm.position[1])>16) and (
abs(itm.position[0])>16 or abs(itm.position[1])>16):
itm.position[0]-=ins[dir][0]
itm.position[1]-=ins[dir][1]
return out
def incrementInIndex(self):
self.inIndex+=1
if self.inIndex>=len(ins):
self.inIndex=0
def incrementOutIndex(self):
self.outIndex+=1
if self.outIndex>=len(outs):
self.outIndex=0
def addItem(self, itm, direction):
self.input[ins.index(direction)].append(itm)
itm.position[0]=64*direction[0]
itm.position[1]=64*direction[1]
def drawBack(self, surface, position):
for x, y in ins:
pygame.draw.line(surface, (0, 225, 0), (x*64+64+position[0],y*64+64+position[1]),(position[0]+64,position[1]+64))
for x, y in outs:
pygame.draw.line(surface, (0, 0, 225), (x*64+64+position[0],y*64+64+position[1]),(position[0]+64,position[1]+64))
def draw(self, surface, position):
for i in itertools.chain((self.limbo,), *itertools.chain(self.input,self.output)):
if i:
assert -64<=i.position[0]<=64 and -64<=i.position[1]<=64, "position is "+str(i.position)
i.draw(surface, (position[0]+i.position[0]+64, position[1]+i.position[1]+64))
return ActualSplitterMerger
def crosser(inOne, outOne, inTwo, outTwo):
class ActualCrosser(Machine):
@staticmethod
def getOutputSides(xoffset, yoffset):
return (xoffset==outOne[0] and yoffset==outOne[1]) or (xoffset==outTwo[0] and yoffset==outTwo[1])
@staticmethod
def getInputSides(xoffset, yoffset):
return (xoffset==inOne[0] and yoffset==inOne[1]) or (xoffset==inTwo[0] and yoffset==inTwo[1])
def __init__(self):
self.trackOneStart=[]
self.trackOneMid=[]
self.trackOneEnd=[]
self.trackTwoStart=[]
self.trackTwoMid=[]
self.trackTwoEnd=[]
def update(self):
toRemove=[]
out=[]
for inp, outp, start, mid, end in ((inOne, outOne, self.trackOneStart, self.trackOneMid, self.trackOneEnd),
(inTwo, outTwo, self.trackTwoStart, self.trackTwoMid, self.trackTwoEnd)):
toRemove.clear()
for item in start:
item.position[0]-=inp[0]
item.position[1]-=inp[1]
if abs(item.position[0])==32 or abs(item.position[1])==32:
toRemove.append(item)
mid.append(item)
for itm in toRemove:
start.remove(itm)
toRemove.clear()
for item in mid:
item.position[0]+=outp[0]-inp[0]
item.position[1]+=outp[1]-inp[1]
if abs(item.position[0])==32 or abs(item.position[1])==32:
toRemove.append(item)
end.append(item)
for item in toRemove:
mid.remove(item)
toRemove.clear()
for item in end:
item.position[0]+=outp[0]
item.position[1]+=outp[1]
if abs(item.position[0])==64 or abs(item.position[1])==64:
toRemove.append(item)
out.append((outp,item))
for item in toRemove:
end.remove(item)
return out
def addItem(self, item, direction):
if (direction==inOne):
item.position[0]=inOne[0]*64
item.position[1]=inOne[1]*64
self.trackOneStart.append(item)
elif (direction==inTwo):
item.position[0]=inTwo[0]*64
item.position[1]=inTwo[1]*64
self.trackTwoStart.append(item)
else:
raise ValueError(direction)
def drawBack(self, surface, position):
for ((x1, y1), (x2,y2)) in ((inOne, outOne), (inTwo, outTwo)):
pygame.draw.lines(surface, (0,100,0), 0,
((position[0]+64+x1*64, position[1]+64+y1*64),
(position[0]+64+x1*32, position[1]+64+y1*32),
(position[0]+64+x2*32, position[1]+64+y2*32),
(position[0]+64+x2*64, position[1]+64+y2*64))
)
def draw(self, surface, position):
for item in itertools.chain(self.trackOneStart, self.trackOneMid, self.trackOneEnd, self.trackTwoStart, self.trackTwoMid, self.trackTwoEnd):
assert -64<=item.position[0]<=64 and -64<=item.position[1]<=64, "position is "+str(item.position)
item.draw(surface, (position[0]+64+item.position[0], position[1]+64+item.position[1]))
return ActualCrosser
def blackHole(entrances):
class ActualBlackHole(Machine):
@staticmethod
def getOutputSides(xoffset, yoffset):
return xoffset==(0,0) and yoffset==(0,0)
@staticmethod
def getInputSides(xoffset, yoffset):
return (xoffset, yoffset) in entrances
def __init__(self):
self.items=[]
def update(self):
l=tuple(((0,0), i) for i in self.items)
self.items.clear()
return l
def addItem(self, item, direction):
self.items.append(item)
def draw(self, surface, position):
pass
def drawBack(self, surface, position):
pygame.draw.circle(surface, (0,0,0), (position[0]+64,position[1]+64), 64)
pygame.draw.circle(surface, (255,255,255), (position[0]+64,position[1]+64), 64,2)
return ActualBlackHole
def whiteHole(entrances):
class ActualWhiteHole(Machine):
@staticmethod
def getOutputSides(xoffset, yoffset):
return (xoffset, yoffset) in entrances
@staticmethod
def getInputSides(xoffset, yoffset):
return xoffset==0 and yoffset==0
def __init__(self):
self.items=[]
self.exitIndex=0
def update(self):
itemscopy=self.items
self.items=[]
out=[]
for i in itemscopy:
self.exitIndex+=1
if self.exitIndex>=len(entrances):
self.exitIndex=0
out.append((entrances[self.exitIndex],i))
return out
def addItem(self, item, direction):
self.items.append(item)
def drawBack(self, surface, position):
pygame.draw.circle(surface, (255,255,255), (position[0]+64,position[1]+64), 62, 0)
def draw(self, surface, position):
pass
return ActualWhiteHole
if __name__=="__main__":
Game().run()
pygame.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment