filterWallType :: (Point -> Bool) -> Point -> WallType -> WallType
filterWallType f (x,y) t =
    let ne    = (x+1,y-1)
        nw    = (x-1,y-1)
        se    = (x+1,y+1)
        sw    = (x-1,y+1)
        north = (x,  y-1)
        south = (x,  y+1)
        west  = (x-1,y)
        east  = (x+1,y)
    in  if t == WallNESW && (f ne || f nw) && (f se || f sw) then t
        else if wallHasN t && wallHasE t && wallHasW t && ((f ne && f nw) || ((f ne || f nw) && f south)) then WallNEW
        else if wallHasS t && wallHasE t && wallHasW t && ((f se && f sw) || ((f se || f sw) && f north)) then WallSEW
        else if wallHasN t && wallHasS t && wallHasE t && ((f ne && f se) || ((f ne || f se) && f west)) then WallNSE
        else if wallHasN t && wallHasS t && wallHasW t && ((f nw && f sw) || ((f nw || f sw) && f east)) then WallNSW
        else if wallHasS t && wallHasW t && (f sw || (f east && f north)) then WallSW
        else if wallHasS t && wallHasE t && (f se || (f west && f north)) then WallSE
        else if wallHasN t && wallHasW t && (f nw || (f east && f south)) then WallNW
        else if wallHasN t && wallHasE t && (f ne || (f west && f south)) then WallNE
        else if (wallHasN t || wallHasS t) && (f west  || f east)  then WallNS
        else if (wallHasW t || wallHasE t) && (f north || f south) then WallEW
        else Wall
filterWallType :: (Point -> Bool) -> Point -> WallType -> WallType
filterWallType f (x,y) t =
    let ne    = (x+1,y-1)
        nw    = (x-1,y-1)
        se    = (x+1,y+1)
        sw    = (x-1,y+1)
        north = (x,  y-1)
        south = (x,  y+1)
        west  = (x-1,y)
        east  = (x+1,y)
    in  if t == WallNESW && (f ne || f nw) && (f se || f sw) then t
        else if wallHasN t && wallHasE t && wallHasW t && ((f ne && f nw) || ((f ne || f nw) && f south)) then WallNEW
        else if wallHasS t && wallHasE t && wallHasW t && ((f se && f sw) || ((f se || f sw) && f north)) then WallSEW
        else if wallHasN t && wallHasS t && wallHasE t && ((f ne && f se) || ((f ne || f se) && f west)) then WallNSE
        else if wallHasN t && wallHasS t && wallHasW t && ((f nw && f sw) || ((f nw || f sw) && f east)) then WallNSW
        else if wallHasS t && wallHasW t && (f sw || (f east && f north)) then WallSW
        else if wallHasS t && wallHasE t && (f se || (f west && f north)) then WallSE
        else if wallHasN t && wallHasW t && (f nw || (f east && f south)) then WallNW
        else if wallHasN t && wallHasE t && (f ne || (f west && f south)) then WallNE
        else if (wallHasN t || wallHasS t) && (f west  || f east)  then WallNS
        else if (wallHasW t || wallHasE t) && (f north || f south) then WallEW
        else Wall
filterWallType f (x,y) t =
    let ne    = (x+1,y-1)
        nw    = (x-1,y-1)
        se    = (x+1,y+1)
        sw    = (x-1,y+1)
        north = (x,  y-1)
        south = (x,  y+1)
        west  = (x-1,y)
        east  = (x+1,y)
    in  if t == WallNESW && (f ne || f nw) && (f se || f sw) then t
        else if wallHasN t && wallHasE t && wallHasW t && ((f ne && f nw) || ((f ne || f nw) && f south)) then WallNEW
        else if wallHasS t && wallHasE t && wallHasW t && ((f se && f sw) || ((f se || f sw) && f north)) then WallSEW
        else if wallHasN t && wallHasS t && wallHasE t && ((f ne && f se) || ((f ne || f se) && f west)) then WallNSE
        else if wallHasN t && wallHasS t && wallHasW t && ((f nw && f sw) || ((f nw || f sw) && f east)) then WallNSW
        else if wallHasS t && wallHasW t && (f sw || (f east && f north)) then WallSW
        else if wallHasS t && wallHasE t && (f se || (f west && f north)) then WallSE
        else if wallHasN t && wallHasW t && (f nw || (f east && f south)) then WallNW
        else if wallHasN t && wallHasE t && (f ne || (f west && f south)) then WallNE
        else if (wallHasN t || wallHasS t) && (f west  || f east)  then WallNS
        else if (wallHasW t || wallHasE t) && (f north || f south) then WallEW
        else Wall