class Laby:
    """un probleme ou on se deplace
    - les actions connues sont N,S,E,O
    - l'etat est un couple (x,y)"""

    """pose des trous dans laby"""
    def __init__(self):
        self.obstacle=[]
        self.ajouterZoneObstacle(-5,-5,0,20)
        self.ajouterZoneObstacle(-5,-5,20,0)
        self.ajouterZoneObstacle(0,15,20,20)
        self.ajouterZoneObstacle(15,0,20,20)
        self.ajouterZoneObstacle(0,3,6,5)
        self.ajouterZoneObstacle(3,9,20,12)
        

        
        
    def ajouterZoneObstacle(self,dx,dy,fx,fy):
        """ajoute un obstacle dans la zone retcangle (dx,dx)->(fx,fy)"""
        for x in range(dx,fx+1):
            for y in range(dy,fy+1):
                self.obstacle+=[(x,y)]
    

      
    def printLaby(self):
        for j in range(-5,20):
            chaine=""
            for i in range(-5,20):
                etat=(i,j)
                if etat in self.obstacle:
                    chaine+="X"
                else:
                    chaine+="."
            print(chaine)
        
        

    def transition(self,s,a):
        """fait evoluer d une unite le systeme"""
        """un etat est le quadruplet ((xdep,ydep),(xprec,yprec))"""
        """action c'est (dx,dy) (delat et delty)"""

        #si on est dans un obstacle, etat = "Mort"
        if ((s=="mort") or (s[0] in self.obstacle)):
            #print("mort")
            return("mort")

        #sinon on fait calcul
        x=s[0][0]
        y=s[0][1]
        
        xPrec=s[1][0]
        yPrec=s[1][1]

        xApres=x+(x-xPrec)
        yApres=y+(y-yPrec)

        xApres=x+a[0]
        yApres=y+a[1]       
        return(((xApres,yApres),(x,y)))
    

    #les recompenses 
    def recompense(self,s,a,sarr):
        
        #si etat est mort, plus d'evolution
        if (sarr=="mort"):
            return(0)    
        
        posFin=sarr[0]
        #si l'etat d arrivee est (14,14) ==> ok
        if ((posFin[0]==14)and(posFin[1]==14)):
            return(100)

        #si l'etat d'arrivee est un obstacle, recompense negative forte
        if (posFin in self.obstacle):
            return(-200)

        #sinon, si on a un obstacle 
        if (posFin[0]==-1)and (posFin[1]==-1):
            return(0)

        #enfin, sinon, cout de 1
        return(-1)

    #la liste des actions
    def actions(self):
        return([(1,0),(1,1),(1,-1),(0,0),(0,1),(0,-1),(-1,0),(-1,-1),(-1,1)])

              
