-- Last modification : 2010/10/28 at 12:05:20
-- Script created by Samy the 2010/09/02 at 15:15:12
-- with PGE Lua v0.02 and PGE Editor v0.03



police = pge.font.load("polices/VERDANA.TTF", 10, PGE_RAM)
pol2 = pge.font.load("polices/BLACKWOLF.TTF", 25, PGE_RAM)
local blanc= pge.gfx.createcolor (255, 255, 255, 255)
pge.gfx.startdrawing ()
pge.gfx.clearscreen ()
pol2:activate ()
pol2:printcenter (125, blanc, "LOADING...")
pge.gfx.enddrawing ()
pge.gfx.swapbuffers ()

--chargement des images
pge.dir.chdir ("Images")
code= pge.texture.load ("code.png", PGE_RAM)
p1_1= pge.texture.load ("p1_1.png", PGE_RAM)
p1_2= pge.texture.load ("p1_2.png", PGE_RAM)
p1_3= pge.texture.load ("p1_3.png", PGE_RAM)
p1_4= pge.texture.load ("p1_4.png", PGE_RAM)
ph1_1= pge.texture.load ("ph1_1.png", PGE_RAM)
ph1_2= pge.texture.load ("ph1_2.png", PGE_RAM)
m1_1= pge.texture.load ("m1_1.png", PGE_RAM)
m1_2= pge.texture.load ("m1_2.png", PGE_RAM)
m1_3= pge.texture.load ("m1_3.png", PGE_RAM)
m1_4= pge.texture.load ("m1_4.png", PGE_RAM)
mh1_1= pge.texture.load ("mh1_1.png", PGE_RAM)
mh1_2= pge.texture.load ("mh1_2.png", PGE_RAM)
mech= pge.texture.load ("p2.png", PGE_RAM)
b1= pge.texture.load ("b1.png", PGE_RAM)
b2= pge.texture.load ("b2.png", PGE_RAM)
b2_1= pge.texture.load ("b2_1.png", PGE_RAM)
b2_2= pge.texture.load ("b2_2.png", PGE_RAM)
b2_3= pge.texture.load ("b2_3.png", PGE_RAM)
b3= pge.texture.load ("b3.png", PGE_RAM)
p2_1= pge.texture.load ("p2_1.png", PGE_RAM)
p2_2= pge.texture.load ("p2_2.png", PGE_RAM)
p2_3= pge.texture.load ("p2_3.png", PGE_RAM)
ech= pge.texture.load ("ech.png", PGE_RAM)
cord= pge.texture.load ("cord.png", PGE_RAM)
tresor= pge.texture.load ("tresor.png", PGE_RAM)
pge.dir.chdir ("..")

--chargement des sons
pge.dir.chdir ("sons")
modification= pge.wav.load ("modif.wav")
debut= pge.wav.load ("debut.wav")
bloc= pge.wav.load ("bloc.wav")
bloc_fin= pge.wav.load ("bloc_fin.wav")
renais= pge.wav.load ("renais.wav")
chute= pge.wav.load ("chute.wav")
pge.wav.volume (chute, 60, 60)
chute_m= pge.wav.load ("mechant_chute.wav")
gagner= pge.wav.load ("gagner.wav")
perdu= pge.wav.load ("perdu.wav")
tresors= pge.wav.load ("tresor.wav")
pge.dir.chdir ("..")

pic= pge.texture.create (480, 272, PGE_PIXEL_FORMAT_8888, PGE_VRAM)

local p= {x = 2, y = 2, dx= 0, dy= 0, dep= 0, ancien= 0, ori= 1}

local STEP= 2      --deplacement en pixel (pour les animations)
local LARGEUR= 16      --largeur des tiles
local ENNEMIS= 3         --nombre d'ennemis
--local LONGUEUR_C= 4   --frequence de renouvellement du pathfinding (en unite de mouvement = 1 bloc graphique)
local TEMPS= 3      --temps avant de commencer a boucher les trous
local TEMPS_E= 2      --temps avant de sortir d'un trou
local TEMPS_R= .5      --temps avant de ressuciter un mechant
local TEMPS_MOUV= .017 --temps entre chaque deplacement de mechant
local TEMPS_MV= .010 --temps entre chaque deplacement du joueur
local QUITTER= false
local nbr_tres= 0
local nbr_attrape= 0
local noir= pge.gfx.createcolor (0, 0, 0, 255)
local vert= pge.gfx.createcolor (0, 255, 0, 255)
local rouge= pge.gfx.createcolor (255, 0, 0, 255)
local larg, haut= 30, 17
local trou= {}
local modif= {}
local niveau= {}
local AI= {}
local time= pge.timer.create ()
local nbre_niv= 0
local max_level= 1
local score= 0
local max_score= 0
local vies= 7
local nom= ""
local opt= {music= true, sounds= true, speed= 0, ia= 4}

for i= 1, 17 do
   niveau[i]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
end


function DessinerNiveau ()
   nbr_tres= 0
   
   pic:settarget ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   for i= 1, haut do
      for j= 1, larg do
         if niveau[i][j]~=0 then
            DessinerTile (j, i, niveau[i][j])
         end
         if niveau[i][j]==5 then
            nbr_tres= nbr_tres+1
         end
      end
   end
   pge.gfx.drawrectoutline (0, 0, larg*LARGEUR, haut*LARGEUR-1, rouge)
   pge.gfx.rendertoscreen ()
   pge.gfx.enddrawing ()
end


function RecreerNiveau (niv)
   local f= io.open ("niveau", "rt")
   local i= 0
   local str
   
   if not niv then
      Erreur ("Problem: No level to load")
      return false
   end
   if not f then
      Erreur ("Problem: can't find file 'niveau' (program cannot run without it)")
      return false
   end
   for line in f:lines () do
      i= i+1
      str= line
      if i==niv or not line then
         break
      end
   end
   if i~=niv or not str then
      f:close ()
      Erreur ("Problem: can't load level "..i+1)
      return false
   end
   
   f:close ()
   local i
   nom= string.match (str, "%<.*%>")
   if #nom>2 then
      nom= string.gsub (nom, "[%<%>]", "")
   else 
      nom= ""
   end
   str= string.sub (str, #nom+3)
   p.x, str= LireNombre (str, 2)
   p.y, str= LireNombre (str, 2)
   
   local j, tx, ty
   j, str= LireNombre (str, 2)
   ENNEMIS= j
   AI= {}
   for k= 1, j do
      tx, str= LireNombre (str, 2)
      ty, str= LireNombre (str, 2)
      AI[k]= {chemin={0}, x= tx, y= ty, dx= 0, dy= 0, dep= 0, compteur= k*3, time= pge.timer.create (), compt= 0, pause= false, ancien= 0, tresor= false, renaissance= false, ori= 1}
   end
   ty, str= LireNombre (str, 2)
   tx, str= LireNombre (str, 2)
   larg, haut= tx, ty
   for j= 1, ty do
      for k= 1, tx do
         niveau[j][k], str= LireNombre (str, 1)
      end
   end
   j, str= LireNombre (str, 2)
   modif= {}
   for k= 1, j do
      tx, str= LireNombre (str, 2)
      ty, str= LireNombre (str, 2)
      i, str= LireNombre (str, 1)
      modif[k]= {x= tx, y= ty, val= i}
   end
   DessinerNiveau ()
   return true
end


function DessinerTile (x, y, val)
   if val==0 then
      pge.gfx.drawrect ((x-1)*LARGEUR, (y-1)*LARGEUR, LARGEUR, LARGEUR, blanc)
   elseif val==1 then
      b1:activate ()
      b1:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==2 then
      b2:activate ()
      b2:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==3 then
      ech:activate ()
      ech:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==4 then
      cord:activate ()
      cord:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==5 then
      tresor:activate ()
      tresor:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==6 then
      b3:activate ()
      b3:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==7 then
      person:activate ()
      person:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   elseif val==8 then
      mech:activate ()
      mech:draw ((x-1)*LARGEUR, (y-1)*LARGEUR)
   end
end


function form (a)
   return string.format ("%02d", a)
end


function EnregistrerNiveau (nom, la, lo, lvl)
   local f=io.open ("niveau", "rt")
   local data
   local tmp= 0
   
   if lvl==0 then
      data= f:read ("*all")
      f:close ()
      
      f= io.open ("niveau", "wt")
      data= string.gsub (data, "\r", "")
      f:write (data)
      f:write ("<".. nom .. ">".. form (p.x) .. form (p.y) .. form (#AI))
      for i= 1, #AI do
         f:write (form (AI[i].x)..form (AI[i].y))
      end
      f:write (form (lo)..form (la))
      for i= 1, lo do
         for j= 1, la do
            f:write ( string.format ("%d", niveau[i][j]))
         end
      end
      f:write (form (#modif))
      for i= 1, #modif do
         f:write (form (modif[i].x)..form (modif[i].y).. modif[i].val)
      end
      f:write ("\n")
      f:close ()
   else 
      data= {}
      for line in f:lines () do
         tmp= tmp+1
         if tmp==lvl then
            line= "<".. nom .. ">".. form (p.x) .. form (p.y) .. form (#AI)
            for i= 1, #AI do
               line= line .. form (AI[i].x)..form (AI[i].y)
            end
            line= line .. form (lo)..form (la)
            for i= 1, lo do
               for j= 1, la do
                  line= line .. string.format ("%d", niveau[i][j])
               end
            end
            line= line .. form (#modif)
            for i= 1, #modif do
               line= line .. form (modif[i].x)..form (modif[i].y).. modif[i].val
            end
         end
         table.insert (data, line)
      end
      f:close ()
      f= io.open ("niveau", "wt")
      for i= 1, #data do
         f:write (data[i].."\n")
      end
      f:close ()
   end
end


function Assurance (msg, aff)
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      if aff then
         pic:activate ()
         pic:draweasy (0, 0)
      else 
         code:activate ()
         code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
      end
      pol2:activate ()
      pol2:printcenter (105, rouge, msg)
      police:activate ()
      police:printcenter (137, vert, "YES: press (X) Cross")
      police:printcenter (149, vert, "NO: press (O) Circle")
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      
      pge.controls.update ()
      if pge.controls.pressed (PGE_CTRL_CIRCLE) then
         return false
      end
      if pge.controls.pressed (PGE_CTRL_CROSS) then
         return true
      end
   end
end


function Edit (lvl)
   local x, y, val= 1, 1, 0
   local la, lo= larg, haut
   local nom= ""
   local mod= false
   
   p= {x= 1, y= 1}
   AI= {}
   person= p1_1
   modif= {}
   for i= 1, 17 do
      niveau[i]= {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   end
   pic:settarget ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   pge.gfx.rendertoscreen ()
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   if lvl>0 then
      if not RecreerNiveau (lvl) then  
         return
      end
   end
   
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      pic:activate ()
      pic:draweasy (0, 0)
      DessinerTile (x, y, val)
      if mod then
         police:activate ()
         police:printcenter (125, vert, "Modfications to do, when player got all treasures")
         pge.gfx.drawrectoutline (0, 0, la*LARGEUR-1, lo*LARGEUR-1, vert)
         for i= 1, #modif do
            DessinerTile (modif[i].x, modif[i].y, modif[i].val)
         end
      else 
         person:activate ()
         person:draw ((p.x-1)*LARGEUR, (p.y-1)*LARGEUR)
         for i= 1, #AI do
            mech:activate ()
            mech:draw ((AI[i].x-1)*LARGEUR, (AI[i].y-1)*LARGEUR)
         end
         pge.gfx.drawrectoutline (0, 0, la*LARGEUR-1, lo*LARGEUR-1, rouge)
      end
      
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      
      pge.controls.update ()
      if pge.controls.pressed (PGE_CTRL_START) then
         if Assurance ("Save this level ?", true) then
            EnregistrerNiveau (nom, la, lo, lvl)
         end
      end
      if pge.controls.pressed (PGE_CTRL_SQUARE) then
         if mod then
            mod= false
         else 
            mod= true
         end
      end
      if (pge.controls.pressed (PGE_CTRL_CROSS) or pge.controls.held (PGE_CTRL_CROSS)) and x<=la and y<=lo then
         pge.gfx.startdrawing ()
         pic:settarget ()
         if not mod then
            if val~=0 then
               if val<=6 then
                  pge.gfx.drawrect ((x-1)*LARGEUR, (y-1)*LARGEUR, LARGEUR, LARGEUR, noir)
                  niveau[y][x]= val
                  DessinerTile (x, y, val)
               elseif val==7 then
                  p.x= x
                  p.y= y
               elseif val==8 then
                  local tmp= true
                  for i= 1, #AI do
                     if AI[i].x==x and AI[i].y==y then
                        tmp= false
                        break
                     end
                  end
                  if tmp then
                     table.insert (AI, 1, {x= x, y= y})
                  end
               end
            else 
               local tmp= false
               for i= 1, #AI do
                  if AI[i].x==x and AI[i].y==y then
                     tmp= i
                     break
                  end
               end
               if tmp then
                  table.remove (AI, tmp)
               end
               pge.gfx.drawrect ((x-1)*LARGEUR, (y-1)*LARGEUR, LARGEUR, LARGEUR, noir)
               niveau[y][x]= 0
            end
         else 
            local tmp= 1
            for i= 1, #modif do
               if modif[i].x==x and modif[i].y==y then
                  if val==0 then
                     table.remove (modif, i)
                  end
                  break
               end
               tmp= tmp+1
            end
            if val~=0 and x<=la and y<=lo then
               modif[tmp]= {x= x, y= y, val= val}
            end
         end
         pge.gfx.rendertoscreen ()
         pge.gfx.enddrawing ()
      end
      if pge.controls.pressed (PGE_CTRL_LTRIGGER) then
         val= val-1
      end
      if pge.controls.pressed (PGE_CTRL_RTRIGGER) then
         val= val+1
      end
      if (not mod and val>8) or (mod and val>5)  then
            val= 0
      end
      if val<0 then
         if not mod then
            val= 8
         else 
            val= 5
         end
      end
      if pge.controls.pressed (PGE_CTRL_LEFT) or pge.controls.analogx ()<-50 then
         x= x-1
      end
      if pge.controls.pressed (PGE_CTRL_RIGHT) or pge.controls.analogx ()>50 then
         x= x+1
      end
      if x<1 then
         x= #niveau[1]
      end
      if x>#niveau[1] then
         x= 1
      end
      if pge.controls.pressed (PGE_CTRL_UP) or pge.controls.analogy ()<-50 then
         y= y-1
      end
      if pge.controls.pressed (PGE_CTRL_DOWN) or pge.controls.analogy ()>50 then
         y= y+1
      end
      if y<1 then
         y= #niveau
      end
      if y> #niveau then
         y= 1
      end
      if pge.controls.pressed (PGE_CTRL_TRIANGLE) then
         la, lo= x, y
         modif= {}
         AI= {}
         p= {x= 1, y= 1}
         pic:settarget ()
         pge.gfx.startdrawing ()
         for i= la+1, #niveau[1] do
            for  j= 1, #niveau do
               pge.gfx.drawrect ((i-1)*LARGEUR, (j-1)*LARGEUR, LARGEUR, LARGEUR, noir)
               niveau[j][i]= 0
            end
         end
         for i= lo+1, #niveau do
            for  j= 1, #niveau[1] do
               pge.gfx.drawrect ((j-1)*LARGEUR, (i-1)*LARGEUR, LARGEUR, LARGEUR, noir)
               niveau[i][j]= 0
            end
         end
         pge.gfx.rendertoscreen ()
         pge.gfx.enddrawing ()
         local i= 1
         while i<= #AI do
            if AI[i].x>la or AI[i].y>lo then
               table.remove (AI, i)
               i=i-1
            end
            i= i+1
         end
      end
      if pge.controls.held (PGE_CTRL_SELECT) then
         if Assurance ("Are you sure to quit the editor ?", false) then
            return
         end
      end
   end
end


function FaireModification ()      --pour atteindre la fin du niveau
   if opt.sounds then
      pge.wav.play (modification)
   end
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   pic:settarget ()
   for i= 1, #modif do
      pge.gfx.drawrect ((modif[i].x-1)*LARGEUR, (modif[i].y-1)*LARGEUR, LARGEUR, LARGEUR, noir)
      DessinerTile (modif[i].x, modif[i].y, modif[i].val)
      niveau[modif[i].y][modif[i].x]= modif[i].val
   end
   pge.gfx.rendertoscreen ()
   pge.gfx.enddrawing ()
end


function Erreur (msg)
   pge.gfx.enddrawing ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   police:activate ()
   police:printcenter (132, blanc, msg)
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   Attendre2 ()
   Attendre ()
end


function LireNombre (str, l)
   local tmp= tonumber (string.sub (str, 1, l))
   if not tmp then
      Erreur ("Unable to read data")
   end
   return tmp, string.sub (str, l+1)
end


function Trou (x, y)      --effacer la case sur l'ecran
   pge.gfx.startdrawing ()
   pic:settarget ()
   pge.gfx.drawrect ((x-1)*LARGEUR, (y-1)*LARGEUR, LARGEUR, LARGEUR, noir)
   pge.gfx.rendertoscreen ()
   pge.gfx.enddrawing ()
end


function VerifierPoint (niv, X, Y, x, y)         --verifier que le point est etudiable (pathfinding)
   if (niv[y][x]~=1 and niv[y][x]~=2)                 --si ce n'est pas un obstacle
   and ((y<Y and niv[Y][X]==3)                    --si on monte il faut une echelle
--   or (y==Y and (niv[Y][X]~=0 or (niv[Y+1][X]~=0 and niv[Y+1][X]~=4 and niv[Y+1][X]~=5)))       --deplacement lateral permis si pas de chute libre
   or (y==Y and (y==haut or (niv[y][x]~=6 and (niv[Y][X]~=6 or (niv[Y+1][X]~=0 and niv[Y+1][X]~=4 and niv[Y+1][X]~=5 and niv[Y+1][X]~=6)) and (((niv[Y][X]~=0 and niv[Y][X]~=5 and niv[y][x]~=6) or (niv[Y+1][X]~=0 and niv[Y+1][X]~=4 and niv[Y+1][X]~=5 and niv[Y+1][X]~=6))))))       --deplacement lateral permis si pas de chute libre
   or y>Y and niv[y][x]~=7)
   then
      return true
   end
   return false
end


function ContourPoint (niv, ferm, ouv, X, Y, g, butX, butY, dX, dY)      --trouver les futurs points a etudier (pathfinding)
   local tmp1, tmp2 
   local ouvt
   local x, y

   for i= 1, 3 do
      if dX <= butX then
         x= X+i-2
      else 
         x= X-i+2
      end
      for j= 1, 3 do
         if dY <= butY then
            y= Y+j-2
         else 
            y= Y-j+2
         end
         pge.controls.update ()
         if pge.controls.held (PGE_CTRL_SELECT) or pge.controls.pressed (PGE_CTRL_SELECT) then
            QUITTER= -1
            return
         end
         if pge.math.fmod ((i+j), 2) ~= 0 then   --pour faire le tour des quatre points horizontaux et verticaux 
            if y>0 and y<=haut and x>0 and x<=larg then   --detection des bordures
               if x == butX and y == butY and VerifierPoint (niv, X, Y, x, y) then   --arrivee a destination
                  table.insert (ferm, 1, {
                     x= x,    --abscisse du point etudie
                     y= y,    --coordonnee du point etudie 
                     pax= X,     --abscisse du parent
                     pay= Y,     --coordonnee du parnt
                     g= g+1,                   --distance parcourue
                     h= pge.math.abs (butX-x)+pge.math.abs (butY-y),              --distance a parcourir
                     f=  0  --valeur du point (g+h)
                  })
                  return true
               end
               if VerifierPoint (niv, X, Y, x, y) then
                  if VerifFerm (ferm, x, y) then                   --si l'element n'a pas deja ete etudie continuer 
                     tmp1, tmp2= VerifOuv (ouv, x, y)
                     if tmp1 then
                        ouvt= {x= x, y= y, pax= X, pay= Y, g= g+1, h= pge.math.abs (butX-x)+pge.math.abs (butY-y), f= 0}
                        ouvt.f= ouvt.g+ouvt.h
                        tmp1= ClassementListeOuverte (ouv, ouvt.f)
                        table.insert (ouv, tmp1, ouvt)
                     else 
                        tmp1= pge.math.abs (butX-x)+pge.math.abs (butY-y) + g+1
                        if tmp1 < ouv[tmp2].f then
                           ouv[tmp2].pax= X
                           ouv[tmp2].pay= Y
                           ouv[tmp2].g= g+1
                           ouv[tmp2].f= tmp1
                        end
                     end
                  end
               end
            end
         end
      end
   end
   return false
end



function CalculerDeplacement (niv, ferm, ouv, dX, dY, butX, butY)      --boucle principal du pathfinding
   ouv= {{
      x= dX,    --abscisse du point etudie
      y= dY,    --coordonnee du point etudie 
      pax= 0,     --abscisse du parent
      pay= 0,     --coordonnee du parnt
      g= 0,    --distance parcourue
      h= pge.math.abs (butX-dX)+pge.math.abs (butY-dY),    --distance a parcourir
      f= pge.math.abs (butX-dX)+pge.math.abs (butY-dY)   --valeur du point (g+h)
      }}
   ferm= {}
   
   time:update ()
   while #ouv > 0 do
      pge.controls.update ()
      if pge.controls.held (PGE_CTRL_SELECT) or pge.controls.pressed (PGE_CTRL_SELECT) then
         QUITTER= -1
         return
      end
      table.insert (ferm, 1, ouv[1])
      table.remove (ouv, 1)
      if  time:peekdelta ()>(0.15+opt.speed*0.15/TEMPS_MV)/ENNEMIS or ContourPoint (niv, ferm, ouv, ferm[1].x, ferm[1].y, ferm[1].g, butX, butY, dX, dY) then
         break
      end
   end

   if #ferm>0 then
      return RetrouverChemin (ferm, dX, dY, butX, butY)
   else 
      return {0}
   end
end


function RetrouverChemin (ferm, dX, dY, butX, butY)      --fin du pathfinding
   local chemin= {}
   local tmp= 1
   local tx, ty= ferm[1].x, ferm[1].y
   local tmpx, tmpy= ferm[1].pax, ferm[1].pay

   while dX~=tx or dY~=ty do
      pge.controls.update ()
      if pge.controls.held (PGE_CTRL_SELECT) or pge.controls.pressed (PGE_CTRL_SELECT) then
         QUITTER= -1
         return
      end
      for i= 1, #ferm do
         if tmpx==ferm[i].x and tmpy==ferm[i].y then
            table.insert (chemin, 1, tx-ferm[i].x-2*(ferm[i].y-ty))
            tx, ty= ferm[i].x, ferm[i].y
            tmpx, tmpy= ferm[i].pax, ferm[i].pay
            table.remove (ferm, i)
            tmp= i
            break
         end
      end
   end
   return chemin
end


function ClassementListeOuverte (ouv, g)       --placer les points a etudier selon leur poids (pathfinding)
   for i= 1, #ouv do
      if g <= ouv[i].g then
         return i
      end
   end
   if #ouv<1 then
      return 1
   end
   return #ouv
end


function VerifFerm (ferm, x, y)   --verifier que l'element n'est pas dans la liste fermee (pathfinding)
   for i= 2, #ferm do   --on commence a 2 car le premier element est celui en cours d'etude
      if ferm[i].x == x and ferm[i].y == y then
         return false
      end
   end
   return true
end


function VerifOuv (ouv, x, y)   --verifier que l'element n'est pas dans la liste ouverte (pathfinding)
   for i= 1, #ouv do
      if ouv[i].x == x and ouv[i].y == y then
         return false, i
      end
   end
   return true
end


function IA (pers, x, y, butx, buty)      -- (pathfinding)
   local ferm= {}
   local ouv= {}
   
   AI[pers].chemin= CalculerDeplacement (niveau, ferm, ouv, x, y, butx, buty)
   ferm= nil
   ouv= nil
end


function PlaceSuivante (x, y, mouv)      --donner les coordonnees apres le deplacement 'mouv'
   if mouv==1 then
      return x+1, y
   elseif mouv==-1 then
      return x-1, y
   elseif mouv==2 then
      return x, y+1
   elseif mouv==-2 then
      return x, y-1
   else 
      return x, y
   end
end


function TesterPlaceEnnemis (pers, mouv, interdit)      --eviter le chevauchement des personnages (en anticipant les deplacements de deux personnages)
   local x_cur, y_cur= 0, 0
   local x_autre, y_autre= 0, 0
   
   x_cur, y_cur= PlaceSuivante (AI[pers].x, AI[pers].y, mouv)
   for i= 1, ENNEMIS do
      if i~=pers  and i~=interdit then
         x_autre, y_autre= PlaceSuivante (AI[i].x, AI[i].y, AI[i].dep)
         if (x_cur==x_autre and y_cur==y_autre and not AI[i].pause) or (x_cur==AI[i].x and y_cur==AI[i].y) then
            AI[pers].pause= mouv
            AI[pers].dep= 0
            return false
         end
      end
   end
   return true
end


function DeplacementAI (pers)      --gerer graphiquement le deplacement des personnages
   local tmp, tmpx, tmpy
   
   if niveau[AI[pers].y][AI[pers].x]==7 then      --s'il est dans un trou
      if AI[pers].dep~=-2 then
         if AI[pers].time:peekdelta ()>=(TEMPS_E+opt.speed*TEMPS_E/TEMPS_MV) then   --sortir du trou
            AI[pers].dep= -2
            trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide= true
            repeat      --pour forcer le deplacement sur le cote en ressortant d'un trou
               tmp= pge.math.randint (0, 2)
               if tmp==0 then
                  tmp= -1
               end
               tmpx, tmpy= PlaceSuivante (AI[pers].x, AI[pers].y, -2)
               if pge.controls.pressed (PGE_CTRL_SELECT) or pge.controls.held (PGE_CTRL_SELECT) then
                  QUITTER= -1
                  return
               end
            until VerifierPoint (niveau, tmpx, tmpy, PlaceSuivante (tmpx, tmpy, tmp))
            AI[pers].chemin= {tmp}
         else 
            AI[pers].ancien= AI[pers].dep
            AI[pers].dep= 0
            if AI[pers].tresor then
               AI[pers].tresor= false
               niveau[AI[pers].y-1][AI[pers].x]= 5
               pic:settarget ()
               tresor:activate ()
               tresor:draweasy ((AI[pers].x-1)*LARGEUR, (AI[pers].y-2)*LARGEUR)
               pge.gfx.rendertoscreen ()
            end
            return
         end
      end
   end
   if AI[pers].dx==0 and AI[pers].dy==0 and niveau[AI[pers].y][AI[pers].x]==5 and not AI[pers].tresor then      --attraper un tresor par un mechant
      pge.wav.volume (tresors, 50+pge.math.floor (50*((p.x-AI[pers].x)/larg)), 50-pge.math.floor (50*((p.x-AI[pers].x)/larg)))
      if opt.sounds then
         pge.wav.play (tresors)
      end
      AI[pers].tresor= true
      niveau[AI[pers].y][AI[pers].x]= 0
      Trou (AI[pers].x, AI[pers].y)
   end
   if AI[pers].dep==1 then
      if AI[pers].dx >=LARGEUR then
         AI[pers].dx= 0
         AI[pers].x= AI[pers].x+1
         AI[pers].ancien= AI[pers].dep
         AI[pers].dep= 0
         if niveau[AI[pers].y][AI[pers].x]==7 and trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide then
            trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide= false
            score= score+75
         end
      else
         AI[pers].dx= AI[pers].dx+STEP
      end
   elseif AI[pers].dep==-1 then
      if AI[pers].dx <=-LARGEUR then
         AI[pers].dx= 0
         AI[pers].x= AI[pers].x-1
         AI[pers].ancien= AI[pers].dep
         AI[pers].dep= 0
         if niveau[AI[pers].y][AI[pers].x]==7 and trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide then
            trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide= false
            score= score+75
         end
      else
         AI[pers].dx= AI[pers].dx-STEP
      end
   elseif AI[pers].dep==-2 then
      if AI[pers].dy <=-LARGEUR then
         AI[pers].dy= 0
         AI[pers].y= AI[pers].y-1
         AI[pers].ancien= AI[pers].dep
         AI[pers].dep= 0
         if niveau[AI[pers].y][AI[pers].x]==7 and trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide then
            trou[RetrouverTrou (AI[pers].x, AI[pers].y)].vide= false
            score= score+75
         end
      else
         AI[pers].dy= AI[pers].dy-STEP
      end
   elseif AI[pers].dep==2 then
      if AI[pers].dy >=LARGEUR then
         AI[pers].dy= 0
         AI[pers].y= AI[pers].y+1
         AI[pers].ancien= AI[pers].dep
         AI[pers].dep= 0
      else
         AI[pers].dy= AI[pers].dy+STEP
      end
   else      --quand le personnage est en pause (pour laisser passer un autre personnage)
      if AI[pers].compt>=LARGEUR then
         AI[pers].compt= 0
         AI[pers].compteur= 0
         AI[pers].pause= false
         IA (pers, AI[pers].x, AI[pers].y, p.x, p.y)
      else 
         AI[pers].compt= AI[pers].compt+STEP
      end
   end
end


function RetrouverTrou (x, y)
   for i= 1, #trou do
      if trou[i].x==x and trou[i].y==y then
         return i
      end
   end
   return false
end


function Perdu ()
   for i= 1, #AI do
      if not AI[i].renaissance then
         if pge.math.abs (AI[i].dep)>=2 or niveau[AI[i].y][AI[i].x]==7 then
            AnimMV (pge.math.abs (AI[i].dy))
         else 
            if niveau[AI[i].y][AI[i].x]~=3 and niveau[AI[i].y][AI[i].x]~=4 then
               AnimMH (pge.math.abs (AI[i].dx))
            else
               AnimMV (pge.math.abs (AI[i].dx))
            end
         end
         mech:activate ()
         if AI[i].ori==1 then
            mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy)
         else 
            mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy, mech:width (), mech:height (), mech:width (), 0, -mech:width (), mech:height ())
         end
      end
   end
   person:activate ()
   if p.ori>0 then
      person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy)
   else 
      person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy, person:width (), person:height (), person:width (), 0, -person:width (), person:height ())
   end
   pol2:activate ()
   pol2:printcenter (125, blanc, "You LOOSE")
   pol2:printcenter (150, blanc, "Score : ".. score)
   pge.gfx.drawrectoutline (0, 0, larg*LARGEUR, haut*LARGEUR-1, rouge)
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
--   if not DEBUGME then
      if pge.mp3.isplaying () then
         pge.mp3.stop ()
      end
--   end
   if opt.sounds then
      pge.wav.play (perdu)
   end
   Attendre2 ()
   Attendre ()
end


function Gagner ()
   score= score+1500
   pge.gfx.enddrawing ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   pic:activate ()
   pic:draweasy (0, 0)
   for i= 1, #AI do
      if not AI[i].renaissance then
         mech:activate ()
         mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy)
      end
   end
   person:activate ()
   person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy)
   pol2:activate ()
   pol2:printcenter (125, vert, "You WIN")
   pol2:printcenter (150, vert, "Score : ".. score)
   pge.gfx.drawrectoutline (0, 0, larg*LARGEUR, haut*LARGEUR-1, rouge)
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   if opt.sounds then
      pge.wav.play (gagner)
   end
   Attendre2 ()
   Attendre ()
end

 
function AnimMH (a)
   if a<=2 then
      mech= m1_1
   elseif a==4 then
      mech= m1_2
   elseif a==6 then
      mech= m1_3
   elseif a==8 then
      mech= m1_4
   elseif a==10 then
      mech= m1_3
   elseif a==12 then
      mech= m1_2
   elseif a>=14 then
      mech= m1_1
   end
end


function AnimMV (a)
   if a<=4 then
      mech= mh1_1
   elseif a<=8 then
      mech= mh1_2
   elseif a<=12 then
      mech= mh1_1
   elseif a<=16 then
      mech= mh1_2
   end
end


function AnimPH (a)
   if a<=2 then
      person= p1_1
   elseif a==4 then
      person= p1_2
   elseif a==6 then
      person= p1_3
   elseif a==8 then
      person= p1_4
   elseif a==10 then
      person= p1_3
   elseif a==12 then
      person= p1_2
   elseif a==14 then
      person= p1_1
   end
end


function AnimPV (a)
   if a<=4 then
      person= ph1_1
   elseif a<=8 then
      person= ph1_2
   elseif a<=12 then
      person= ph1_1
   elseif a<=16 then
      person= ph1_2
   end
end


function Jeu (lvl)
   local str
   if not RecreerNiveau (lvl) then
      return -1
   end
   person= p1_1
   if opt.sounds then
      pge.wav.play (debut)
   end
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   pic:activate ()
   pic:draweasy (0, 0)
   mech= m1_1
   for i = 1, #AI do
      mech:activate ()
      mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy)
   end
   person:activate ()
   person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy)
   pge.gfx.drawrectoutline (0, 0, larg*LARGEUR, haut*LARGEUR-1, rouge)
   pol2:activate ()
   pol2:printcenter (125, vert, nom)
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   pge.controls.update ()
   while not pge.controls.heldany () and pge.math.abs (pge.controls.analogx ())<50 and pge.math.abs (pge.controls.analogy ())<50 do
      pge.controls.update ()
   end
--   while pge.controls.held (PGE_CTRL_SQUARE) or pge.controls.held (PGE_CTRL_CIRCLE) do
--      pge.controls.update ()
--   end
   Attendre ()
   while not pge.controls.heldany () and pge.math.abs (pge.controls.analogx ())<50 and pge.math.abs (pge.controls.analogy ())<50 do
      pge.controls.update ()
   end
   if opt.music then
      pge.mp3.loop (true)
      pge.mp3.play ("sons/drive.mp3")
   end
   while pge.running () do
      if QUITTER then
         return QUITTER
      end
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      pic:activate ()
      pic:draweasy (0, 0)
      for i= 1, #AI do
         if not AI[i].renaissance then
            if pge.math.abs (p.x+p.dx/LARGEUR-(AI[i].x+AI[i].dx/LARGEUR))<0.6 and pge.math.abs (p.y+p.dy/LARGEUR-(AI[i].y+AI[i].dy/LARGEUR))<1 then
               Perdu ()
               QUITTER= 1
            end
            if pge.math.abs (AI[i].dep)>=2 or niveau[AI[i].y][AI[i].x]==7 then
               AnimMV (pge.math.abs (AI[i].dy))
            else 
               if niveau[AI[i].y][AI[i].x]~=3 and niveau[AI[i].y][AI[i].x]~=4 then
                  AnimMH (pge.math.abs (AI[i].dx))
               else
                  AnimMV (pge.math.abs (AI[i].dx))
               end
            end
            
            mech:activate ()
            if AI[i].ori==1 then
               mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy)
            else 
               mech:draw ((AI[i].x-1)*LARGEUR+AI[i].dx, (AI[i].y-1)*LARGEUR+AI[i].dy, mech:width (), mech:height (), mech:width (), 0, -mech:width (), mech:height ())
            end
            if AI[i].time:peekdelta ()>=(TEMPS_MOUV+opt.speed*TEMPS_MOUV/TEMPS_MV) then
               if niveau[AI[i].y][AI[i].x]~=7 then         --si pas bloque dans un trou
                  AI[i].time:update ()
                  if AI[i].dep==0 and not AI[i].pause then
                     if AI[i].compteur >= opt.ia or #AI[i].chemin<=0 then
                        AI[i].compteur= 0
                        IA (i, AI[i].x, AI[i].y, p.x, p.y)
                        if QUITTER then
                           return
                        end
                     end
                     AI[i].compteur= AI[i].compteur+1
                     AI[i].dep= AI[i].chemin[1]
                     table.remove (AI[i].chemin, 1)
                     if not AI[i].dep then
                        AI[i].dep= 0
                     end
                     if AI[i].dep==1 then
                        AI[i].ori= 1
                     elseif AI[i].dep==-1 then
                        AI[i].ori= -1
                     end
                     if AI[i].y<haut and niveau[AI[i].y+1][AI[i].x]==7 and niveau[AI[i].y][AI[i].x]~=7 and niveau[AI[i].y][AI[i].x]~=4 and AI[i].ancien~=-2 and trou[RetrouverTrou (AI[i].x, AI[i].y+1)].vide then      --tomber dans un trou
                        AI[i].dep= 2
                        trou[RetrouverTrou (AI[i].x, AI[i].y+1)].vide= false
                        score= score+75
                        pge.wav.volume (chute_m, 50+pge.math.floor (50*((p.x-AI[i].x)/larg)), 50-pge.math.floor (50*((p.x-AI[i].x)/larg)))
                        if opt.sounds then
                           pge.wav.play (chute_m)
                        end
                     end
                     TesterPlaceEnnemis (i, AI[i].dep, 0)
                  end
               end
               DeplacementAI (i)
            end
         else 
            if AI[i].time:peekdelta ()<(TEMPS_R+0.5+opt.speed*TEMPS_R/TEMPS_MV) then
               p2_1:activate ()
               p2_1:draweasy ((AI[i].x-1)*LARGEUR, (AI[i].y-1)*LARGEUR)
            elseif AI[i].time:peekdelta ()>=(TEMPS_R+0.5+opt.speed*TEMPS_R/TEMPS_MV) and AI[i].time:peekdelta ()<(TEMPS_R+1+opt.speed*TEMPS_R/TEMPS_MV) then
               p2_2:activate ()
               p2_2:draweasy ((AI[i].x-1)*LARGEUR, (AI[i].y-1)*LARGEUR)
            elseif AI[i].time:peekdelta ()>=(TEMPS_R+1+opt.speed*TEMPS_R/TEMPS_MV) and AI[i].time:peekdelta ()<(TEMPS_R+1.5+opt.speed*TEMPS_R/TEMPS_MV) then
               p2_3:activate ()
               p2_3:draweasy ((AI[i].x-1)*LARGEUR, (AI[i].y-1)*LARGEUR)
            elseif AI[i].time:peekdelta ()>=(TEMPS_R+1.5+opt.speed*TEMPS_R/TEMPS_MV) then
               AI[i].renaissance= false
               AI[i].dep= 0
               AI[i].dx, AI[i].dy= 0, 0
               IA (i, AI[i].x, AI[i].y, p.x, p.y)
            end
         end
      end
      person:activate ()
      if p.ori>0 then
         person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy)
      else 
         person:draw ((p.x-1)*LARGEUR+p.dx, (p.y-1)*LARGEUR+p.dy, person:width (), person:height (), person:width (), 0, -person:width (), person:height ())
      end
      do      --animation trous
         i= 1
         while i<=#trou do
            if trou[i].time:peekdelta ()>=(TEMPS+opt.speed*TEMPS/TEMPS_MV) and trou[i].time:peekdelta ()<(TEMPS+0.5+opt.speed*TEMPS/TEMPS_MV) then
               b2_1:activate ()
               b2_1:draweasy ((trou[i].x-1)*LARGEUR, (trou[i].y-1)*LARGEUR)
            elseif trou[i].time:peekdelta ()>=(TEMPS+0.5+opt.speed*TEMPS/TEMPS_MV) and trou[i].time:peekdelta ()<(TEMPS+1+opt.speed*TEMPS/TEMPS_MV) then
               b2_2:activate ()
               b2_2:draweasy ((trou[i].x-1)*LARGEUR, (trou[i].y-1)*LARGEUR)
            elseif trou[i].time:peekdelta ()>=(TEMPS+1+opt.speed*TEMPS/TEMPS_MV) and trou[i].time:peekdelta ()<(TEMPS+1.5+opt.speed*TEMPS/TEMPS_MV) then
               b2_3:activate ()
               b2_3:draweasy ((trou[i].x-1)*LARGEUR, (trou[i].y-1)*LARGEUR)
            elseif trou[i].time:peekdelta ()>=(TEMPS+1.5+opt.speed*TEMPS/TEMPS_MV) then
               pge.gfx.enddrawing ()
               pge.gfx.enddrawing ()
               pge.wav.volume (bloc_fin, 50+pge.math.floor (50*((p.x-trou[i].x)/larg)), 50-pge.math.floor (50*((p.x-trou[i].x)/larg)))
               if opt.sounds then
                  pge.wav.play (bloc_fin)
               end
               pic:settarget ()
               pge.gfx.startdrawing ()
               b2:activate ()
               b2:draweasy ((trou[i].x-1)*LARGEUR, (trou[i].y-1)*LARGEUR)
               pge.gfx.rendertoscreen ()
               pge.gfx.enddrawing ()
               local tmpx, tmpy
               tmpx, tmpy= PlaceSuivante (p.x, p.y, p.dep)
               if (p.x==trou[i].x and p.y==trou[i].y) or (tmpx==trou[i].x and tmpy==trou[i].y) then
                  Perdu ()
                  QUITTER= 1
               end
               for j= 1, ENNEMIS do
                  tmpx, tmpy= PlaceSuivante (AI[j].x, AI[j].y, AI[j].dep)
                  if (trou[i].x==AI[j].x and trou[i].y==AI[j].y) or (trou[i].x==tmpx and trou[i].y==tmpy) then
                     if AI[j].tresor then
                        AI[j].tresor= false
                        niveau[trou[i].y-1][trou[i].x]= 5
                        pic:settarget ()
                        tresor:activate ()
                        tresor:draweasy ((trou[i].x-1)*LARGEUR, (trou[i].y-2)*LARGEUR)
                        pge.gfx.rendertoscreen ()
                     end
                     AI[j].renaissance= true
                     repeat
                        AI[j].x= pge.math.randint (1, larg)
                        AI[j].y= pge.math.randint (2, 5)
                     until niveau[AI[j].y][AI[j].x]~=2 and niveau[AI[j].y][AI[j].x]~=1
                     pge.wav.volume (renais, 50+pge.math.floor (50*((p.x-AI[j].x)/larg)), 50-pge.math.floor (50*((p.x-AI[j].x)/larg)))
                     if opt.sounds then
                        pge.wav.play (renais)
                     end
                     break
                  end
               end
               niveau[trou[i].y][trou[i].x]= 2
               table.remove (trou, i)
               i= i-1
            end
            i= i+1
         end
      end
      pge.gfx.drawrectoutline (0, 0, larg*LARGEUR, haut*LARGEUR-1, rouge)
      pol2:activate ()
      pol2:print (480-pge.font.measure (pol2, vies), 219, blanc, vies)
      str= nbr_attrape .."/"..nbr_tres
      if nbr_attrape~=nbr_tres then
         pol2:print (480-pge.font.measure (pol2, str), 0, rouge, str)
      else 
         pol2:print (480-pge.font.measure (pol2, str), 0, vert, str)
      end
      pol2:print (480-pge.font.measure (pol2, score), 240, blanc, score)
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      time:update ()
      while time:peekdelta ()<opt.speed do
         pge.controls.update ()
         if pge.controls.held (PGE_CTRL_START) or pge.controls.pressed (PGE_CTRL_START) then
            Options ()
         end
         if pge.controls.held (PGE_CTRL_SELECT) or pge.controls.pressed (PGE_CTRL_SELECT) then
            QUITTER= -1
            return QUITTER
         end
         if (pge.controls.held (PGE_CTRL_SQUARE) or pge.controls.pressed (PGE_CTRL_SQUARE)) and lvl>1 then   --revenir d'un niveau d'un niveau
            QUITTER= 3
            return QUITTER
         end
      end
      pge.controls.update ()
      if pge.controls.held (PGE_CTRL_START) or pge.controls.pressed (PGE_CTRL_START) then
         Options ()
      end
      if pge.controls.held (PGE_CTRL_SELECT) or pge.controls.pressed (PGE_CTRL_SELECT) then
         QUITTER= -1
      end
      if (pge.controls.held (PGE_CTRL_SQUARE) or pge.controls.pressed (PGE_CTRL_SQUARE)) and lvl>1 then   --revenir d'un niveau d'un niveau
         QUITTER= 3
      end
--      if (pge.controls.held (PGE_CTRL_CIRCLE) or pge.controls.pressed (PGE_CTRL_CIRCLE)) and lvl<max_level then   --passer d'un niveau
      if (pge.controls.held (PGE_CTRL_CIRCLE) or pge.controls.pressed (PGE_CTRL_CIRCLE)) then   --passer d'un niveau
         QUITTER= 2
      end
      if p.dep == 1 then
         if p.dx >=LARGEUR then
            p.dx= 0
            p.x= p.x+1
            p.ancien= 1
            p.dep= 0
         else 
            p.dx= p.dx+STEP
            if niveau[p.y][p.x]~=3 and niveau[p.y][p.x]~=4 then
               AnimPH (p.dx)
            else 
               AnimPV (p.dx)
            end
         end
      elseif p.dep == -1 then
         if p.dx <=-LARGEUR then
            p.dx= 0
            p.x= p.x-1
            p.ancien= -1
            p.dep= 0
         else 
            p.dx= p.dx-STEP
            if niveau[p.y][p.x]~=3 and niveau[p.y][p.x]~=4 then
               AnimPH (pge.math.abs (p.dx))
            else 
               AnimPV (pge.math.abs (p.dx))
            end
         end
      elseif p.dep == -2 then
         if p.dy <=-LARGEUR then
            p.dy= 0
            p.y= p.y-1
            p.ancien= -2
            p.dep= 0
         else 
            p.dy= p.dy-STEP
            AnimPV (pge.math.abs (p.dy))
         end
      elseif p.dep == 2 then
         if p.dy >=LARGEUR then
            p.dy= 0
            p.y= p.y+1
            p.ancien= 2
            p.dep= 0
         else 
            p.dy= p.dy+STEP
            AnimPV (p.dy)
         end
      end
      if niveau[p.y][p.x] == 5 then
         pge.wav.volume (tresors, 100, 100)
         if opt.sounds then
            pge.wav.play (tresors)
         end
         niveau[p.y][p.x] = 0
         score= score+250
         nbr_attrape= nbr_attrape+1
         Trou (p.x, p.y)
         if nbr_attrape==nbr_tres then
            FaireModification ()
         end
      end
      if p.dep == 0 then      --personnage tombe
         if p.y<haut and niveau[p.y+1][p.x]~=1 and niveau[p.y+1][p.x] ~= 2 and niveau[p.y+1][p.x] ~= 3 and niveau[p.y][p.x] ~= 3 and niveau[p.y][p.x] ~= 4 then
--         if p.y<haut and (niveau[p.y+1][p.x]==0 or niveau[p.y+1][p.x]==5 or niveau[p.y+1][p.x]==8 or (niveau[p.y+1][p.x]==7 and trou[RetrouverTrou (p.x, p.y+1)].vide)) and niveau[p.y][p.x]~=3 and niveau[p.y][p.x]~=4 then
            if niveau[p.y+1][p.x]~=7 or trou[RetrouverTrou (p.x, p.y+1)].vide then
               if p.ancien~=2 and opt.sounds then
                  pge.wav.play (chute)
               end
               p.dep= 2
            end
         end
      end
      if p.dep == 0 then
         --trou a gauche et a droite
         if pge.controls.pressed (PGE_CTRL_LTRIGGER) then
            if p.y<haut and niveau[p.y+1][p.x-1]==2 and (niveau[p.y][p.x-1]==0 or niveau[p.y][p.x-1]==7 or niveau[p.y][p.x-1]==4) and ((niveau[p.y][p.x]==0 and niveau[p.y+1][p.x]~=0 and niveau[p.y+1][p.x]~=4 and niveau[p.y+1][p.x]~=7) or niveau[p.y][p.x]==4 or niveau[p.y][p.x]==3 or niveau[p.y][p.x]==7) then
               p.ori= -1
               niveau[p.y+1][p.x-1]= 7
               Trou (p.x-1, p.y+1)
               table.insert (trou, {x= p.x-1, y= p.y+1, time= pge.timer.create (), vide= true})
               pge.wav.volume (bloc, 100, 70)
               if opt.sounds then
                  pge.wav.play (bloc)
               end
            end
         end
         if pge.controls.pressed (PGE_CTRL_RTRIGGER) then
            if p.y<haut and niveau[p.y+1][p.x+1]==2 and (niveau[p.y][p.x+1]==0 or niveau[p.y][p.x+1]==7 or niveau[p.y][p.x+1]==4) and ((niveau[p.y][p.x]==0 and niveau[p.y+1][p.x]~=0 and niveau[p.y+1][p.x]~=4 and niveau[p.y+1][p.x]~=7) or niveau[p.y][p.x]==4 or niveau[p.y][p.x]==3 or niveau[p.y][p.x]==7) then
               p.ori= 1
               niveau[p.y+1][p.x+1]= 7
               Trou (p.x+1, p.y+1)
               table.insert (trou, {x= p.x+1, y= p.y+1, time= pge.timer.create (), vide= true})
               pge.wav.volume (bloc, 70, 100)
               if opt.sounds then
                  pge.wav.play (bloc)
               end
            end
         end
         --deplacement personnage
         if p.x>1 and (pge.controls.analogx ()<-50 or pge.controls.held (PGE_CTRL_LEFT) or pge.controls.pressed (PGE_CTRL_LEFT)) and niveau[p.y][p.x-1]~=1 and niveau[p.y][p.x-1]~=2 and niveau[p.y][p.x-1]~=6 then
            p.dep= -1
            p.ori= -1
         end
         if p.x<larg and (pge.controls.analogx ()>50 or pge.controls.held (PGE_CTRL_RIGHT) or pge.controls.pressed (PGE_CTRL_RIGHT)) and niveau[p.y][p.x+1]~=1 and niveau[p.y][p.x+1]~=2 and niveau[p.y][p.x+1]~=6 then
            p.dep= 1
            p.ori= 1
         end
         if (pge.controls.analogy ()>50 or pge.controls.held (PGE_CTRL_DOWN) or pge.controls.pressed (PGE_CTRL_DOWN)) and p.y<haut and niveau[p.y+1][p.x]~=1 and niveau[p.y+1][p.x]~=2 then
            if not (niveau[p.y][p.x]==3 or niveau[p.y+1][p.x]==3) then
               if opt.sounds then
                  pge.wav.play (chute)
               end
            end
            p.dep= 2
         end
         if niveau[p.y][p.x] == 3 and (p.y==1 or (niveau[p.y-1][p.x] ~= 1 and niveau[p.y-1][p.x] ~= 2)) and (pge.controls.analogy ()<-50 or pge.controls.held (PGE_CTRL_UP) or pge.controls.pressed (PGE_CTRL_UP)) then
            p.dep= -2
            if p.y==1 then
               if nbr_tres==nbr_attrape then
                  Gagner ()
                  QUITTER= 2
               else
                  p.dep= 0
               end
            end
         end
      end
   end
end


function Intro ()
   local i, j= 0, 1
--   if not DEBUGME then
      pge.mp3.loop (false)
      pge.mp3.play ("sons/intro.mp3")
--   end
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      code:activate ()
      code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, i)
      if j<0 and i<60 then
         pol2:activate ()
         pol2:printcenter (125, blanc, "PRESS A KEY")
      end
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      time:update ()
      while time:peekdelta ()<0.02 do
      end
      pge.controls.update ()
      if pge.controls.pressedany () then
         pge.wav.play (renais)
         break
      end
      if j<0 and i<60 then
         pge.controls.update ()
         Attendre2 ()
         Attendre ()
         break
      end
      i= i+j
      if i>=200 then
         j= -5
      end
   end
--   if not DEBUGME then
      if pge.mp3.isplaying () then
         pge.mp3.stop ()
      end
--   end 
end


function CompterNiveaux ()
   local f= io.open ("niveau", "rt")
   if not f then
      return false
   end

   nbre_niv= 0
   for line in f:lines () do
      nbre_niv= nbre_niv + 1
   end
   f:close ()
   return nbre_niv
end


function ChargerStat ()
   local f= io.open ("stats", "rt")
   if not f then
      return false
   end
   
   local str= f:read ("*all")
   max_level, str= LireNombre (str, 3)

   max_score= LireNombre (str, #str)
   
   f:close ()
   return true
end


function EnregistrerStats ()
   local f= io.open ("stats", "wt")
   if not f then
      return false
   end
   if score>=max_score then
      max_score= score
      f:write ( string.format ("%03d%d", max_level, score))
   end

   f:close ()
   return true
end


function Credits ()
   Attendre ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   code:activate ()
   code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
   pol2:activate ()
   pol2:printcenter (0, rouge, "Credit goes to:")
   police:activate ()
   police:print (0, 35, blanc, "* Douglas E. Smith (conceptor of the game : 'Lode Runner')")
   police:print (0, 50, blanc, "* InsertWittyName for developping PGE lua for the PSP")
   police:print (0, 65, blanc, "* Rich Gast for the 'blackwolf' font (coolgrafik.com)")
   police:print (0, 80, blanc, "* Apocalyptica for the wonderful song 'Drive'")
   police:print (0, 95, blanc, "* All website who share sounds (unfortunately i can't remember where all sounds came)")
   police:print (0, 110, blanc, "* blogue.mesfinances.branchez-vous.com for the background picture")
   police:print (0, 125, blanc, "* All people who help(ed) to free the PSP to the good side of the underground.")
   police:print (0, 250, vert, "Contact me on my blog: samy-prog.blogspot.com")
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   Attendre2 ()
   Attendre ()
end


function Instructions ()
   Attendre ()
   pge.gfx.startdrawing ()
   pge.gfx.clearscreen ()
   code:activate ()
   code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
   pol2:activate ()
   pol2:printcenter (0, rouge, "Level editor")
   police:activate ()
   police:print (0, 35, blanc, "TRIANGLE to set the size of the level")
   police:print (0, 50, blanc, "Left and Right TRIGGER to change patterns")
   police:print (0, 65, blanc, "SQUARE to set patterns to access the end of the level (must go to the roof)")
   police:print (0, 80, blanc, "START to save level")
   police:print (0, 95, blanc, "SELECT to quit the editor")
   police:print (0, 150, rouge, "Beware: there is no verifications about: ")
   police:print (0, 175, blanc, "         - the accessibility ot the end of the level")
   police:print (0, 190, blanc, "         - the place of player")
   police:print (0, 205, blanc, "         - modifications outside of the borders")
   pge.gfx.enddrawing ()
   pge.gfx.swapbuffers ()
   Attendre2 ()
   Attendre ()
end


function BoucleJeu (lvl)
   local  reuss
   
   while pge.running () do
      QUITTER= false
      nbr_attrape= 0
      p= {x = 2, y = 2, dx= 0, dy= 0, dep= 0, ancien= 0, ori= 1}
      AI= {}
      modif= {}
      trou= {}
      reuss= Jeu (lvl)
      if pge.mp3.isplaying () then
         pge.mp3.stop ()
      end
      
      if reuss==-1 then
         break
      end
      if reuss==1 then
         vies= vies-1
         if score>=max_score then
            if not EnregistrerStats () then 
               Erreur ("Can't write file 'stats'")
            end
         end
         if vies<=0 then
            score= 0
            pge.gfx.startdrawing ()
            pge.gfx.clearscreen ()
            code:activate ()
            code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
            pol2:activate ()
            pol2:printcenter (125, rouge, "Game over.")
            pge.gfx.enddrawing ()
            pge.gfx.swapbuffers ()
            Attendre2 ()
            Attendre ()
            vies= 7
            break
         end
      end
      if reuss==3 then
         if lvl>1 then
            lvl= lvl-1
         end
      end
      if reuss==2 then
         lvl= lvl+1
         if lvl>max_level then
            max_level= lvl
         end
         if score>max_score then
            max_score= score
         end
      end
   end
end


function ChoixValeur (msg, dep, min, max, ecart, param)
   local val= dep
   local tmp
   if param then
      tmp= ObtenirNom (dep)
   end
   Attendre ()
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      code:activate ()
      code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
      pol2:activate ()
      pol2:print (0, 50, blanc, msg)
      pol2:printcenter (125, rouge, val)
      if param then
         pol2:printcenter (150, vert, tmp)
      end
      police:activate ()
      police:print (0, 230, vert, "Press (X) Cross to accept new value")
      police:print (0, 250, vert, "Press (O) Circle to undo")
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      pge.controls.update ()
      if pge.controls.pressed (PGE_CTRL_CIRCLE) then
         Attendre ()
         return -99
      end
      if pge.controls.pressed (PGE_CTRL_CROSS) then
         Attendre ()
         break
      end
      if pge.controls.pressed (PGE_CTRL_LEFT) or pge.controls.pressed (PGE_CTRL_DOWN) or pge.controls.analogx ()<-50 or pge.controls.analogy ()<-50 then
         if val>min then
            val= val-ecart
            if opt.sounds then
               pge.wav.volume (tresors, 100, 100)
               pge.wav.play (tresors)
            end
            if param then
               tmp= ObtenirNom (val)
            end
         end
      end
      if pge.controls.pressed (PGE_CTRL_RIGHT) or pge.controls.pressed (PGE_CTRL_UP) or pge.controls.analogx ()>50 or pge.controls.analogy ()>50 then
         if val<max then
            val= val+ecart
            if opt.sounds then
               pge.wav.volume (tresors, 100, 100)
               pge.wav.play (tresors)
            end
            if param then
               tmp= ObtenirNom (val)
            end
         end
      end
   end
   return val
end


function ObtenirNom (n)
   local tmp= 0
   local f= io.open ("niveau", "rt")
   for line in f:lines () do
      tmp= tmp+1
      if tmp==n then
         tmp= string.match (line, "%<.*%>")
         if #tmp>2 then
            tmp= string.gsub (tmp, "[%<%>]", "")
         else 
            tmp= "user " .. n
         end
         f:close ()
         return tmp
      end
   end
   f:close ()
   return "Error"
end


function Attendre ()
   while pge.controls.heldany () or pge.controls.pressedany () do
      pge.controls.update ()
   end
end


function Attendre2 ()
   while not pge.controls.heldany () do
      pge.controls.update ()
   end
end


function PrintTrueFalse (val)
   if val then
      return "On"
   else 
      return "Off"
   end
end


function InvTrueFalse (val)
   if val then
      return false
   else 
      return true
   end
end


function Options ()
   local place= 1
   local items= {
      {nom= "music :", val= opt.music, msg= false},
      {nom= "sounds :", val= opt.sounds, msg= false},
      {nom= "speed :", val= 50-1000*opt.speed, msg= false, },
      {nom= "IA :", val= 20-opt.ia, msg= "how much movements before the IA find a new way to you"}
   }
   local tmp
   pge.gfx.enddrawing ()
   Attendre ()
   
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
--      code:activate ()
--      code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
      pic:activate ()
      pic:draw (0, 0, pic:width (), pic:height (), 0, 0, pic:width (), pic:height (), 0, 30)
      pol2:activate ()
      pol2:printcenter (0, rouge, "Options")
      for i= 1, #items do
         if place==i then
            pol2:activate ()
            pol2:print (0, 50*i-15, vert, items[i].nom)
            if type (items[i].val)=="boolean" then
               pol2:print (pge.font.measure (pol2, items[i].nom)+10, 50*i-15, rouge, PrintTrueFalse (items[i].val))
           else 
              pol2:print (pge.font.measure (pol2, items[i].nom)+10, 50*i-15, rouge, items[i].val)
            end
         else 
            police:activate ()
            police:print (0, 50*i, blanc, items[i].nom)
            if type (items[i].val)=="boolean" then
               police:print (pge.font.measure (police, items[i].nom)+10, 50*i, vert, PrintTrueFalse (items[i].val))
           else 
              police:print (pge.font.measure (police, items[i].nom)+10, 50*i, vert, items[i].val)
            end
         end
         if items[i].msg then
            police:activate ()
            police:print (480-pge.font.measure (police, items[i].msg), 50*i, blanc, items[i].msg)
         end
      end
      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      pge.controls.update ()
      if pge.controls.pressed (PGE_CTRL_START) or pge.controls.pressed (PGE_CTRL_CIRCLE) then
         Attendre ()
         return
      end
      if pge.controls.pressed (PGE_CTRL_CROSS) then
         if opt.sounds then
            pge.wav.volume (bloc, 100, 100)
            pge.wav.play (bloc)
         end
         if place==1 then
            items[place].val= InvTrueFalse (items[place].val)
            opt.music= items[place].val
            if items[place].val then
               pge.mp3.loop (true)
               pge.mp3.play ("sons/drive.mp3")
            else 
               if pge.mp3.isplaying () then
                  pge.mp3.stop ()
               end
            end
         elseif place==2 then
            items[place].val= InvTrueFalse (items[place].val)
            opt.sounds= items[place].val
         elseif place==3 then
            tmp= ChoixValeur ("Choose speed of the game : ", items[place].val, 0, 50, 1, false)
            if tmp>=0 then
                items[place].val= tmp
                opt.speed= (50-tmp)/1000
            end
         elseif place==4 then
            tmp= ChoixValeur ("Choose reactivity of IA : ", items[place].val, 0, 19, 1, false)
            if tmp>=0 then
               items[place].val= tmp
                opt.ia= 20-tmp
            end
         end
      end
      if pge.controls.pressed (PGE_CTRL_DOWN) or pge.controls.analogy ()<-50 then
         place= place+1
         if opt.sounds then
            pge.wav.volume (tresors, 100, 100)
            pge.wav.play (tresors)
         end
      end
      if pge.controls.pressed (PGE_CTRL_UP) or pge.controls.analogy ()>50 then
         place= place-1
         if opt.sounds then
            pge.wav.volume (tresors, 100, 100)
            pge.wav.play (tresors)
         end
      end
      if place<1 then
         place= #items
      end
      if place>#items then
         place= 1
      end
   end
end


function Menu ()
   local place= 1
   local x, y= 200, 150
   local tmp= 0
   local taille= 1
   local item= {{pic= pge.texture.load ("Images/nouveau.png", PGE_RAM)},
                {pic= pge.texture.load ("Images/charger.png", PGE_RAM)},
                {pic= pge.texture.load ("Images/edit.png", PGE_RAM)},
                {pic= pge.texture.load ("Images/creer.png", PGE_RAM)},
                {pic= pge.texture.load ("Images/options.png", PGE_RAM)},
                {pic= pge.texture.load ("Images/credits.png", PGE_RAM)}
                }
   local ratio= item[1].pic:width ()/item[1].pic:height ()
   local lvl= 1

   nbre_niv= CompterNiveaux ()
   if not nbre_niv then
      Erreur ("Can't access the levels in 'niveau'")
   end
   if not ChargerStat () then
      Erreur ("Can't load file 'stats'")
   end

   
   while pge.running () do
      pge.gfx.startdrawing ()
      pge.gfx.clearscreen ()
      code:activate ()
      code:draw (0, 0, 480, 272, 0, 0, code:width (), code:height (), 0, 30)
      
      for i= 1, #item do
         if tmp>0 then
            if i==place-1 then
               taille= 20*pge.math.abs (200-x)/95
            elseif i==place then
               taille= 20-20*pge.math.abs (200-x)/95
            else 
               taille= 0
            end
         elseif tmp<0 then
            if i==place+1 then
               taille= 20*pge.math.abs (200-x)/95
            elseif i==place then
               taille= 20-20*pge.math.abs (200-x)/95
            else 
               taille= 0
            end
         else 
            if i==place then
               taille= 20
            else
               taille= 0
            end
         end
         item[i].pic:activate ()
         item[i].pic:draw (x+(i-place)*95-taille/2, y-(taille*ratio)/2, item[i].pic:width ()+taille, item[i].pic:height ()+taille*ratio, 0, 0, item[i].pic:width (), item[i].pic:height (), 0, 255)
      end
      
      pol2:activate ()
      pol2:print (30, 50, vert, "LORD RUNNER")

      pol2:printcenter (80, blanc, "Higher level: ".. max_level)       
      pol2:printcenter (100, blanc, "Highscore: ".. max_score)       

      police:activate ()
      police:print (0, 255, blanc, "Written by Samy (C) 2010")

      pge.gfx.enddrawing ()
      pge.gfx.swapbuffers ()
      pge.controls.update ()
      if (pge.controls.pressed (PGE_CTRL_LEFT) or pge.controls.analogx ()<-50) and place>1 and tmp==0 then
         tmp= 5
      end
      if (pge.controls.pressed (PGE_CTRL_RIGHT) or pge.controls.analogx ()>50) and place<#item and tmp==0 then
         tmp= -5
      end
      if pge.controls.pressed (PGE_CTRL_START)  then
         pic:toram ()
         pic= nil
         collectgarbage ()
         return
      end

      if pge.controls.pressed (PGE_CTRL_CROSS) and tmp==0 then
         if place==1 then
            if (max_level==1 and score==0) or Assurance ("All data will be erased! Continue ?", false) then
               lvl= 1
               max_score= 0
               score= 0
               BoucleJeu (lvl)
            end
         elseif place==2 then
            tmp= ChoixValeur ("Choose your level to play : ", lvl, 1, CompterNiveaux (), 1, true)
            score= 0
            if tmp>0 then
               lvl= tmp
               BoucleJeu (lvl)
            end
            tmp= 0
         elseif place==3 then
            tmp= ChoixValeur ("Choose your level to edit : ", lvl, 1, CompterNiveaux (), 1, true)
            if tmp>0 then
               Instructions ()
               lvl= tmp
               Edit (lvl)
            end
            tmp= 0
         elseif place==4 then
            Instructions ()
            Edit (0)
         elseif place==5 then
            Options ()
         elseif place==6 then
            Credits ()
         end
      end

      x= x+tmp
      if x<=105 then
         x= 200
         tmp= 0
         place= place+1
         pge.wav.volume (tresors, 100, 100)
         pge.wav.play (tresors)
      end
      if x>=295 then
         x= 200
         tmp= 0
         place= place-1
         pge.wav.volume (tresors, 100, 100)
         pge.wav.play (tresors)
      end
   end
end


Intro ()
Menu ()
