diff --git a/Jeu_2048/game2048.cpp b/Jeu_2048/game2048.cpp
index 8427ae7a129a2d4f6d6befcae2cc83362d12864c..5f9d183607261e99dbb881a100ee6149e33fa10a 100644
--- a/Jeu_2048/game2048.cpp
+++ b/Jeu_2048/game2048.cpp
@@ -35,53 +35,185 @@ QVector<int> Game2048::board() const {
 }
 
 void Game2048::spawnTile() {
-    QVector<QPair<int,int>> emptyTiles;
-    for (int row = 0; row < 4; row++) {
-        for (int col = 0; col < 4; col++) {
-            if (m_board[row][col] == 0)
-                flatBoard.append(row * 4 + col);
-        }
-    }
-    if (!flatBoard.isEmpty()) {
-        int randIndex = QRandomGenerator::global()->bounded(flatBoard.size());
-        int index = flatBoard[randIndex];
-        int row = index / 4;
-        int col = index % 4;
-        m_board[row][col] = (QRandomGenerator::global()->bounded(10) == 0) ? 4 : 2;
+    QVector<QPair<int,int>> emptyPositions;
+    for(int i=0; i<4; i++)
+        for(int j=0; j<4; j++)
+            if(m_board[i][j] == 0)
+                emptyPositions.append(qMakePair(i,j));
+
+    if(!emptyPositions.isEmpty()) {
+        int randIndex = QRandomGenerator::global()->bounded(emptyPositions.size());
+        auto pos = emptyPositions[randIndex];
+        m_board[pos.first][pos.second] = (QRandomGenerator::global()->bounded(10)==0) ? 4 : 2;
     }
 }
 
+
 bool Game2048::moveLeft() {
     bool moved = false;
-    // Implémentation à venir
+    for(int i=0; i<4; i++) { // Pour chaque ligne, on compresse, fusionne et re compresse
+        // Compression à gauche
+        for(int k=0; k<3; k++)
+            for(int j=0; j<3; j++)
+                if(m_board[i][j]==0 && m_board[i][j+1]!=0) {
+                    m_board[i][j]=m_board[i][j+1];
+                    m_board[i][j+1]=0;
+                    moved=true;
+                }
+        // Fusion
+        for(int j=0; j<3; j++)
+            if(m_board[i][j]!=0 && m_board[i][j]==m_board[i][j+1]) {
+                m_board[i][j]*=2;
+                m_score+=m_board[i][j];
+                m_board[i][j+1]=0;
+                moved=true;
+            }
+        // Recompression après fusion
+        for(int k=0; k<3; k++)
+            for(int j=0; j<3; j++)
+                if(m_board[i][j]==0 && m_board[i][j+1]!=0) {
+                    m_board[i][j]=m_board[i][j+1];
+                    m_board[i][j+1]=0;
+                }
+    }
+    if(moved) {
+        spawnTile();
+        updateGameState();
+        emit boardChanged();
+        emit scoreChanged();
+    }
     return moved;
 }
 
 bool Game2048::moveRight() {
     bool moved = false;
-    // Implémentation à venir
+    for(int i=0; i<4; i++) { // Pour chaque ligne, on compresse, fusionne et re compresse
+        // Compression à droite
+        for(int k=0; k<3; k++)
+            for(int j=3; j>0; j--)
+                if(m_board[i][j]==0 && m_board[i][j-1]!=0) {
+                    m_board[i][j]=m_board[i][j-1];
+                    m_board[i][j-1]=0;
+                    moved=true;
+                }
+        // Fusion
+        for(int j=3; j>0; j--)
+            if(m_board[i][j]!=0 && m_board[i][j]==m_board[i][j-1]) {
+                m_board[i][j]*=2;
+                m_score+=m_board[i][j];
+                m_board[i][j-1]=0;
+                moved=true;
+            }
+        // Recompression après fusion
+        for(int k=0; k<3; k++)
+            for(int j=3; j>0; j--)
+                if(m_board[i][j]==0 && m_board[i][j-1]!=0) {
+                    m_board[i][j]=m_board[i][j-1];
+                    m_board[i][j-1]=0;
+                }
+    }
+    if(moved) {
+        spawnTile();
+        updateGameState();
+        emit boardChanged();
+        emit scoreChanged();
+    }
     return moved;
 }
 
 bool Game2048::moveUp() {
     bool moved = false;
-    // Implémentation à venir
+    for(int j=0; j<4; j++) { // Pour chaque colonne, on compresse, fusionne et re compresse
+        // Compression à droite
+        for(int k=0; k<3; k++)
+            for(int i=0; i<3; i++)
+                if(m_board[i][j]==0 && m_board[i+1][j]!=0) {
+                    m_board[i][j]=m_board[i+1][j];
+                    m_board[i+1][j]=0;
+                    moved=true;
+                }
+        // Fusion
+        for(int i=0; i<3; i++)
+            if(m_board[i][j]!=0 && m_board[i][j]==m_board[i+1][j]) {
+                m_board[i][j]*=2;
+                m_score+=m_board[i][j];
+                m_board[i+1][j]=0;
+                moved=true;
+            }
+        // Recompression après fusion
+        for(int k=0; k<3; k++)
+            for(int i=0; i<3; i++)
+                if(m_board[i][j]==0 && m_board[i+1][j]!=0) {
+                    m_board[i][j]=m_board[i+1][j];
+                    m_board[i+1][j]=0;
+                }
+    }
+    if(moved) {
+        spawnTile();
+        updateGameState();
+        emit boardChanged();
+        emit scoreChanged();
+    }
     return moved;
 }
 
+
 bool Game2048::moveDown() {
     bool moved = false;
-    // Implémentation à venir
+    for(int j=0; j<4; j++) { // Pour chaque colonne, on compresse, fusionne et re compresse
+        // Compression à droite
+        for(int k=0; k<3; k++)
+            for(int i=3; i>0; i--)
+                if(m_board[i][j]==0 && m_board[i-1][j]!=0) {
+                    m_board[i][j]=m_board[i-1][j];
+                    m_board[i-1][j]=0;
+                    moved=true;
+                }
+        // Fusion
+        for(int i=3; i>0; i--)
+            if(m_board[i][j]!=0 && m_board[i][j]==m_board[i-1][j]) {
+                m_board[i][j]*=2;
+                m_score+=m_board[i][j];
+                m_board[i-1][j]=0;
+                moved=true;
+            }
+        // Recompression après fusion
+        for(int k=0; k<3; k++)
+            for(int i=3; i>0; i--)
+                if(m_board[i][j]==0 && m_board[i-1][j]!=0) {
+                    m_board[i][j]=m_board[i-1][j];
+                    m_board[i-1][j]=0;
+                }
+    }
+    if(moved) {
+        spawnTile();
+        updateGameState();
+        emit boardChanged();
+        emit scoreChanged();
+    }
     return moved;
 }
 
+bool Game2048::canMove() const {
+    for (int i=0; i<4; i++){
+        for (int j=0; j<4; j++){
+            if (m_board[i][j]==0){
+                return true;
+            }
+            if (i<3 && m_board[i][j]==m_board[i+1][j]){
+                return true;
+            }
+            if (j<3 && m_board[i][j]==m_board[i][j+1]){
+                return true;
+            }
+        }
+    }
+    return true;
+}
+
+
 void Game2048::updateGameState() {
     if (!canMove()) {
         emit gameOver();
     }
 }
-
-bool Game2048::canMove() const {
-    // Implémentation basique à compléter
-    return true;
-}