Source

wd_pys60 / wd_maze.py

#doorDic={("H",(0,0)):<"class":Door>}
rooms=[]
closedDoors=[]
freeRoom,aboutToFreeRoom=[],[]

doorDic={}
roomDic={}
LENGTH=12
roomNum=18
blobsize=1
doorColor=0x00ff00
peopleColor=0x00ff00
PEOPLE_SIZE=LENGTH/2
UP_KEY=50
DOWN_KEY=56
LEFT_KEY=52
RIGHT_KEY=54
directionDic={"north":(0,1),"south":(0,-1),"east":(1,0),"west":(-1,0)}
reverseDirectionDic=dict([(v,k) for (k,v) in directionDic.items()])
def divTuple(t1,t2):
    return [t1-t2 for t1,t2 in zip(t1,t2)]
def plusTuple(t1,t2):
    return [t1+t2 for t1,t2 in zip(t1,t2)]
def disrupt(li):
	import random
	data=[]
	ALL_NUM=li
	tnum=ALL_NUM
	for i in range(len(ALL_NUM)):
		data.append(random.choice(tnum))
		tnum=[num for num in tnum if not num in data]
	return data
def northPos(pos):
    return (pos[0],pos[1]+1)
def southPos(pos):
    return (pos[0],pos[1]-1)
def eastPos(pos):
    return (pos[0]+1,pos[1])
def westPos(pos):
    return (pos[0]-1,pos[1])
def mapPos(pos):
    return (pos[0],320-pos[1])
def allPos(pos):
    return [northPos(pos),southPos(pos),eastPos(pos),westPos(pos)]
#print mapPos((5,5))
import appuifw
from graphics import *
import e32
from key_codes import *
import random

class ZeroPosition:
    def __init__(self,length=LENGTH,zeroPos=(0,0)):
        self.length=length
        self.roomZeroPos=(zeroPos[0]+1+length/2,zeroPos[1]+length/2)
        self.hZeroPos=(zeroPos[0]+1+length/2,zeroPos[1])
        self.sZeroPos=(zeroPos[0],zeroPos[1]+1+length/2)

zeroPos=ZeroPosition(zeroPos=(0,0))
class People:
    def __init__(self,length=LENGTH):
        self.length=length
        self.startPos,self.endPos=(0,0),(roomNum-1,roomNum-1)
        #self.startPos=(random.randint(0,roomNum-1),random.randint(0,roomNum-1))
        #self.endPos=(random.randint(0,roomNum-1),random.randint(0,roomNum-1))
        self.nowPos=self.startPos
        self.nowRoom=roomDic[self.nowPos]
    def trunTo(self,direction):
        #print self.nowPos
        if direction=="up":
            if self.nowRoom.northDoor.isOpen():
                self.nowPos=(self.nowPos[0],self.nowPos[1]+1)
            else:
                return False
        elif direction=="down":
            if self.nowRoom.southDoor.isOpen():
                self.nowPos=(self.nowPos[0],self.nowPos[1]-1)
            else:
                return False
        elif direction=="right":
            if self.nowRoom.eastDoor.isOpen():
                self.nowPos=(self.nowPos[0]+1,self.nowPos[1])
            else:
                return False
        elif direction=="left":
            if self.nowRoom.westDoor.isOpen():
                self.nowPos=(self.nowPos[0]-1,self.nowPos[1])
            else:
                return False
        self.nowRoom=roomDic[self.nowPos]
        #print self.nowRoom.northDoor.isOpen(),self.nowRoom.southDoor.isOpen(),self.nowRoom.westDoor.isOpen(),self.nowRoom.eastDoor.isOpen()
        return True
class Door:
    def __init__(self,position,type,length=LENGTH):
        """type can be "H" or "S" position:(0,0)"""
        self.state="closed"
        self.length,self.type,self.position=length,type,position
        if self.type=="H":
            self.screenPos=(zeroPos.hZeroPos[0]+position[0]*length,zeroPos.hZeroPos[1]+position[1]*length)
            self.displayTuple=((self.screenPos[0]-length/2,self.screenPos[1]),(self.screenPos[0]+length/2,self.screenPos[1]))
        elif self.type=="S":
            self.screenPos=(zeroPos.sZeroPos[0]+position[0]*length,zeroPos.sZeroPos[1]+position[1]*length)
            self.displayTuple=((self.screenPos[0],self.screenPos[1]-length/2),(self.screenPos[0],self.screenPos[1]+length/2))
        global doorDic
        if not doorDic.has_key((type,position)):
            doorDic[(type,position)]=self
    def close(self):
        self.state="closed"
        closedDoors.append(self)
    def open(self):
        self.state="open"
        closedDoors.remove(self)
    def isOpen(self):
        if self.state=="open":
            return True
        else:
            return False

class Room:
    def __init__(self,position,type="normal",length=50):
        """type can be "playRoom" or "restRoom" position:(0,0)"""
        self.length,self.type,self.position=length,type,position
        self.free=False
        self.screenPos=(zeroPos.roomZeroPos[0]+position[0]*length,zeroPos.roomZeroPos[1]+position[1]*length)
        if not doorDic.has_key(("H",(position[0],position[1]+1))):
            self.northDoor=Door(length=length,type="H",position=(position[0],position[1]+1))
        else:
            self.northDoor=doorDic[("H",(position[0],position[1]+1))]
        if not doorDic.has_key(("H",position)):
            self.southDoor=Door(length=length,type="H",position=position)
        else:
            self.southDoor=doorDic[("H",position)]

        if not doorDic.has_key(("S",(position[0]+1,position[1]))):
            self.eastDoor=Door(length=length,type="S",position=(position[0]+1,position[1]))
        else:
            self.eastDoor=doorDic[("S",(position[0],position[1]+1))]
        if not doorDic.has_key(("S",position)):
            self.westDoor=Door(length=length,type="S",position=position)
        else:
            self.westDoor=doorDic[("S",position)]
    def unFreeRooms(self):
        unFreeRooms=[]
        for pos in allPos(self.position):
            try:
                if not roomDic[pos].isFree():
                    unFreeRooms.append(roomDic[pos])
            except:
                pass
        return unFreeRooms
    def freeRoom(self,room):
        try:
            eval("self.%sDoor"%reverseDirectionDic[tuple(divTuple(room.position,self.position))]).open()
            room.free=True
        except:
            pass
    def isFree(self):
        return self.free

#--#--#--#--#--#--#--
for x in range(roomNum):
    for y in range(roomNum):
        room=Room(position=(x,y),length=LENGTH)
        rooms.append(room)
        roomDic[room.position]=room
people=People()
for item in doorDic.items():
    door=item[1]
    if door.state=="closed":
        closedDoors.append(door)
#--#--#--#--#--#--#--

appuifw.app.screen='full'
img=None
myfont=u'Sans MT 936_S60'

def handle_event(event):
    return None
def handle_redraw(rect):
    if img:
        img.clear(0)
        for door in closedDoors:
            img.line((mapPos(door.displayTuple[0]),mapPos(door.displayTuple[1])),0x00ff00,width=blobsize)

        #for rm in freeRoom:
            #img.point(mapPos(rm.screenPos),0xffffff,width=LENGTH-1)

        #for rm in aboutToFreeRoom:
            #img.point(mapPos(rm.screenPos),0x00ffff,width=PEOPLE_SIZE)

        img.point(mapPos(people.nowRoom.screenPos),0x00ff00,width=PEOPLE_SIZE)
        img.point(mapPos(roomDic[people.endPos].screenPos),0x00ffff,width=PEOPLE_SIZE)
        canvas.blit(img)

appuifw.app.body=canvas=appuifw.Canvas(
    event_callback=handle_event,
    redraw_callback=handle_redraw)
img=Image.new(canvas.size)
running=1
def quit():
    global running
    running=0
appuifw.app.exit_key_handler=quit

def drawpoint():
    global img
    img.point((random.randint(0,240),random.randint(0,320)),0x00ff00,width=blobsize)
    handle_redraw(())
def openDoor(doorKey=("S",(0,2))):
    try:
        closedDoors.remove(doorDic[doorKey])
        doorDic[doorKey].state="open"        
    except:
        #print "already opened"
        pass
def closeDoor(doorKey=("S",(0,2))):
    try:
        closedDoors.append(doorDic[doorKey])
        doorDic[doorKey].state="closed"  
    except:
        #print "already closed"
        pass

appuifw.app.body.bind(49,openDoor)
appuifw.app.body.bind(42,closeDoor)

appuifw.app.body.bind(UP_KEY,lambda:people.trunTo("up"))
appuifw.app.body.bind(DOWN_KEY,lambda:people.trunTo("down"))
appuifw.app.body.bind(LEFT_KEY,lambda:people.trunTo("left"))
appuifw.app.body.bind(RIGHT_KEY,lambda:people.trunTo("right"))
def generateMaze():
    global freeRoom,aboutToFreeRoom
    freeRoom=[people.nowRoom]
    nextRoom=freeRoom[-1]
    aboutToFreeRoom=[]
    aboutToFreeRoom.extend(disrupt(people.nowRoom.unFreeRooms()))
    step=0
    while len(freeRoom)!=2  or step==0 or step==1:
        #aboutToFreeRoom=[]
        if step>=0:
            if disrupt(people.nowRoom.unFreeRooms()):
                aboutToFreeRoom.extend(disrupt(people.nowRoom.unFreeRooms()))
                nextRoom=aboutToFreeRoom[-1]
                freeRoom.append(people.nowRoom)
            else:
                nextRoom=freeRoom[-2]
                freeRoom.pop()

        step+=1
        people.nowRoom.freeRoom(nextRoom)
        people.nowPos=nextRoom.position
        people.nowRoom=nextRoom
        #del aboutToFreeRoom[-1]
        #print reverseDirectionDic[tuple(divTuple(aboutToFreeRoom[-1].position,people.nowRoom.position))]
        handle_redraw(())
        e32.ao_sleep(0.00000001)
generateMaze()

running=1
while running!=0:
    #img.clear(0)
    running+=1
    #color=random.randint(0,0xffffff)
    for i in range(roomNum*2,running,-1):
        do=random.choice([openDoor])
        #do(doorKey=random.choice(doorDic.keys()))
    
    #if people.nowPos==people.endPos:
        #print "done"
        #quit()
    handle_redraw(())
    #print len(closedDoors)
    e32.ao_sleep(0.000001)

#--#--#--#--#--#--#--
#print doorDic.keys()
#print len(closedDoors)