diff --git a/bucher.lua b/bucher.lua
index 91a6a7abb6a342b351151e447684ad46ba7ad5c4..937132778c2ebb4e4be8f00ed491693a8c8f6fba 100644
--- a/bucher.lua
+++ b/bucher.lua
@@ -31,20 +31,122 @@ function RSI_Bucheron:print()
     self.base_:print()
 end
 
+
 ---
 -- \brief Abattre un arbre
 -- \return bool Succès
 function RSI_Bucheron:chopTree()
-    --TODO: Implementer
+    local success
+    local countMovedUp = 0
+
+    success = self.base_:dig(ID_LOG)
+    if (not success)
+    then
+        return false
+    end
+
+    success = self.base_:forward()
+
+    print("Chopping down")
+    while ( self.base_:dig(ID_LOG, "down") ) do self.base_:down() end
+    print("Moving up")
+
+    -- Remonter pour couper les bûches vers le haut. Essaie de trouver des
+    -- bûches sur quelques blocs de haut avant d'abandonner et redescendre.
+    while (countMovedUp < 3 and self.base_:up())
+    do
+        countMovedUp = countMovedUp + 1
+        printf("Moved up %d\n", countMovedUp)
+    end
+
+    print("Chopping up")
+    while ( self.base_:dig(ID_LOG, "up") ) do self.base_:up() end
+    self.base_:ground()
+
+    return success
 end
 
+
+---
+-- \brief Couper les arbres tout en avançant le long d'une ligne
+-- \param int   distance  Nombre de blocs à parcourir
+-- \return bool Succès
+function RSI_Bucheron:moveChop(distance)
+    --TODO: Implémenter
+    local success = true
+    local traveled = 0
+
+    self:chopTree()
+    self.base_:ground()
+    self.base_:climb()
+
+    while (traveled < distance) and turtle.forward()
+    do
+        self:chopTree()
+        self.base_:ground()
+        self.base_:climb()
+        self:chopTree()
+
+        traveled = traveled + 1
+    end
+
+    if self.facing_ == 0 then
+        self.base_.pos_["x"] = self.base_.pos_["x"] + traveled
+    elseif self.base_.facing_ == 3 then
+        self.base_.pos_["z"] = self.base_.pos_["z"] + traveled
+    elseif self.base_.facing_ == 6 then
+        self.base_.pos_["x"] = self.base_.pos_["x"] - traveled
+    elseif self.base_.facing_ == 9 then
+        self.base_.pos_["z"] = self.base_.pos_["z"] - traveled
+    end
+
+    return (traveled == distance)
+end
+
+
 ---
 -- \brief Couper les arbres dans la zone
--- \param int nLignes   Nombre de lignes
--- \param int nColonnes Nombre de colonnes
+-- \param int lines Nombre de lignes
+-- \param int cols  Nombre de colonnes
 -- \return bool Succès
-function RSI_Bucheron:main(nLignes, nColonnes)
+function RSI_Bucheron:chopArea(lines, cols)
     --TODO: Implementer
+    local success = true
+
+    assert(lines >= 1)
+    assert(cols >= 1)
+
+    -- La ligne de la case de départ compte comme 1
+    lines = lines - 1
+
+    self.base_:ground()
+    self:chopTree()
+
+    for i=1,cols,1
+    do
+        print("Debut de colonne.")
+        success = self:moveChop(lines) -- FIXME: Remplacer moveForward par moveChop
+        self.base_:ground()
+        self.base_:climb()
+
+        if not success
+        then
+            return success
+        end
+
+        if ( (i%2) == 0 )
+        then
+            success = self.base_:left(true)
+            self.base_:turnLeft()
+        else
+            success = self.base_:right(true)
+            self.base_:turnRight()
+        end
+        self:chopTree()
+
+    end
+    return success
 end
 
-return RSI_Bucheron
+
+return RSI_Bucheron
\ No newline at end of file
diff --git a/rsiTurtle.lua b/rsiTurtle.lua
index aa0965c891dab31ff07f8145e863ec221631aee5..91ed1756811f56fcbc95b927fe1e1e05219890de 100644
--- a/rsiTurtle.lua
+++ b/rsiTurtle.lua
@@ -556,13 +556,85 @@ end
 ---
 -- \brief Vérifier si l'ID du bloc en face contient la regex
 -- \param string    blockIdRegex   Regex correspondant au bloc à vérifier
+-- \param string    side           Direction parmi: front, back, up, down, left, right
+--                                 Si vide, prend "front" par défaut
 -- \return bool Bloc en face match la regex
-function RSI_Turtle:facesBlock(blockIdRegex)
-    local isNotAir, blockData = turtle.inspect()
+function RSI_Turtle:facesBlock(blockIdRegex, side)
+    local isNotAir, blockData
+
+    if side == nil
+    then
+        side = "front"
+    end
+
+    if side == "up"
+    then
+        isNotAir, blockData = turtle.inspectUp()
+    elseif side == "down"
+    then
+        isNotAir, blockData = turtle.inspectDown()
+    elseif side == "front"
+    then
+        isNotAir, blockData = turtle.inspect()
+    elseif side == "back"
+    then
+        self:turn180()
+        isNotAir, blockData = turtle.inspect()
+    elseif side == "left"
+    then
+        self:turnLeft()
+        isNotAir, blockData = turtle.inspect()
+    elseif side == "right"
+    then
+        self:turnRight()
+        isNotAir, blockData = turtle.inspect()
+    end
+
     if (isNotAir)
     then
         return string.match(blockData.name, blockIdRegex)
+    else
+        return false
     end
 end
 
+
+---
+-- \brief Casser un bloc dans la direction souhaitée
+-- \param string    blockIdRegex    Regex correspondant au bloc à casser.
+--                                  Si vide, casse n'importe quoi.
+-- \param string    side            Direction parmi: front, back, up, down, left, right
+--                                  Si vide, prend "front" par défaut
+-- \return bool Succès
+function RSI_Turtle:dig(blockIdRegex, side)
+    --TODO: Tester
+    local success
+
+    if blockIdRegex == nil
+    then
+        blockIdRegex = ''
+    end
+
+    if side == nil
+    then
+        side = "front"
+    end
+
+    if (self:facesBlock(blockIdRegex, side))
+    then
+        if (side == "up")
+        then
+            success = turtle.digUp()
+        elseif (side == "down")
+        then
+            success = turtle.digDown()
+        else
+            success = turtle.dig()
+        end
+    end
+
+    return success
+end
+
+
 return RSI_Turtle
diff --git a/test.lua b/test.lua
index 3870b88cfae58a206681058116b609f4ba37a3e1..7d46a295fa481cf6399d840b152a1e8c8683ccdd 100644
--- a/test.lua
+++ b/test.lua
@@ -10,19 +10,19 @@ rsiE = require("excaver")
 
 require("bloc_ids")
 
-rsiT.helloWorld()
+-- rsiT.helloWorld()
 
-print("Test de RSI_Turtle")
-t = rsiT:init()
-t:print()
+-- print("Test de RSI_Turtle")
+-- t = rsiT:init()
+-- t:print()
 
 print("Test de RSI_Bucheron")
 b = rsiB:init()
 b:print()
 
-print("Test de RSI_Excavatrice")
-e = rsiE:init()
-e:print()
+-- print("Test de RSI_Excavatrice")
+-- e = rsiE:init()
+-- e:print()
 
 -- print("Test de l'API turtle")
 -- print(turtle.inspect())
@@ -75,10 +75,10 @@ e:print()
 -- print("Test moveBackward;")
 -- t:moveBackward(5)
 
-function checkPos(x,y,z)
-    xPos, yPos, zPos = t:getPos()
-    return ( xPos == x and yPos == y and zPos == z )
-end
+-- function checkPos(x,y,z)
+--     xPos, yPos, zPos = t:getPos()
+--     return ( xPos == x and yPos == y and zPos == z )
+-- end
 
 -- print("Tests face;")
 -- for i=0,9,3
@@ -151,12 +151,37 @@ end
 -- assert(t:goThroughArea(15, 15, true, nil))
 -- assert(t:goThroughAreaGrounded(3, 3, turtle.placeUp))
 
-print("Tests facesBlock")
-assert(t:facesBlock(ID_LOG))
+--print("Tests facesBlock")
+--assert(t:facesBlock(ID_LOG))
+--assert(t:facesBlock(ID_LOG, "front"))
+--assert(t:facesBlock(ID_LOG, "back"))
+--assert(t:facesBlock(ID_LOG, "down"))
+--assert(t:facesBlock(ID_LOG, "up"))
+--assert(t:facesBlock(ID_LOG, "right"))
+--assert(t:facesBlock(ID_LOG, "left"))
+
+-- print("Test dig")
+--assert(b.base_:dig(ID_LOG, "left"))
+--b.base_:face(12)
+--assert(b.base_:dig(ID_LOG, "right"))
+--b.base_:face(12)
+--assert(b.base_:dig(ID_LOG, "front"))
+--b.base_:face(12)
+--assert(b.base_:dig(ID_LOG, "back"))
+--b.base_:face(12)
+--assert(b.base_:dig(ID_LOG, "down"))
+--b.base_:face(12)
+--assert(b.base_:dig(ID_LOG, "up"))
+
+--print("Test chopTree")
+--assert(b:chopTree())
+
+print("Test chopArea")
+assert(b:chopArea(15, 20))
 
-assert(t:moveToOrigin())
-print(t:getPos())
-assert(checkPos(0,0,0))
+-- assert(t:moveToOrigin())
+-- print(t:getPos())
+-- testassert(checkPos(0,0,0))
 
 print("Fin des tests")