diff --git a/forms/interface.ui b/forms/interface.ui
index a7367fcd035c29818be0818e7646acee4059c8d0..c059c4401f2bf0385f71421fb491fefbdf46b8ba 100644
--- a/forms/interface.ui
+++ b/forms/interface.ui
@@ -629,6 +629,7 @@ pattern recorded :</string>
      <string>Extra</string>
     </property>
     <addaction name="action_bad_apple"/>
+    <addaction name="action_snake"/>
    </widget>
    <addaction name="menuFichier"/>
    <addaction name="menuEditer"/>
@@ -669,6 +670,11 @@ pattern recorded :</string>
     <string>Open configuration</string>
    </property>
   </action>
+  <action name="action_snake">
+   <property name="text">
+    <string>Play Snake</string>
+   </property>
+  </action>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/include/interface.hpp b/include/interface.hpp
index ae51e1f6aaf357af8979dafcd4fb67078f695887..5a44b3190b1c08b3169e90c8bf1279c54bf899ba 100644
--- a/include/interface.hpp
+++ b/include/interface.hpp
@@ -147,8 +147,13 @@ private:
     //! \brief Fonction secrète !
     void play_bad_apple();
 
+    //! \brief Surprise aussi...
+    void play_snake();
+
 protected:
     void closeEvent(QCloseEvent* e) override;
+    void keyPressEvent(QKeyEvent *event) override;
+    void keyReleaseEvent(QKeyEvent *event) override;
 
 private:
     Ui::MainWindow *ui;
@@ -157,6 +162,7 @@ private:
     NeighborhoodRule* m_neighborhood_rule;
     QJsonObject m_loaded_model;
     QTimer* timer;
+    bool m_arrow_key_state[4];
     bool m_customizing;
 };
 #endif // MAINWINDOW_HPP
diff --git a/src/interface.cpp b/src/interface.cpp
index 468b7540a4fbce6a78f0d21b262eb44413d30a04..0ebac53dd69d108952eb6042abfe59ed29921692 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -20,6 +20,7 @@
 #include <QInputDialog>
 #include <QTimer>
 #include <QElapsedTimer>
+#include <QKeyEvent>
 
 #if QT_VERSION_MAJOR == 5
 #define BAD_APPLE_AUDIO
@@ -32,12 +33,13 @@
 
 MainWindow::MainWindow(QWidget *parent)
     : QMainWindow(parent)
-    , ui(new Ui::MainWindow)
-    , simulation()
-    , timer(new QTimer(this))
-    , m_customizing(false)
+      , ui(new Ui::MainWindow)
+      , simulation()
+      , timer(new QTimer(this))
+      , m_customizing(false)
 {
     ui->setupUi(this);
+    std::fill(std::begin(m_arrow_key_state), std::end(m_arrow_key_state), false);
 
     m_transition_rule = nullptr;
     m_neighborhood_rule = nullptr;
@@ -50,31 +52,32 @@ MainWindow::MainWindow(QWidget *parent)
     connect(ui->struct_library, &StructureLibraryView::structure_copied, this, &MainWindow::copy_structure_clicked);
     connect(ui->grid_view, &GridView::zoom_changed, ui->struct_library, &StructureLibraryView::update_cell_pixel_size);
     connect(ui->statesSettingsButton, &QPushButton::clicked, this, [this]
-    {
-        ColorLabel* dialog = new ColorLabel(simulation.getAlphabet(), this);
-        if (dialog->exec())
-        {
-            ui_update_alphabet(dialog->getAlphabet());
-        }
-    });
+            {
+                ColorLabel* dialog = new ColorLabel(simulation.getAlphabet(), this);
+                if (dialog->exec())
+                {
+                    ui_update_alphabet(dialog->getAlphabet());
+                }
+            });
     connect(ui->transition_list, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this](int)
-    { update_transition_settings(); });
+            { update_transition_settings(); });
     connect(ui->action_open_configuration, &QAction::triggered, this, [this] { on_openPatternButton_clicked(); });
     connect(ui->action_bad_apple, &QAction::triggered, this, &MainWindow::play_bad_apple);
+    connect(ui->action_snake, &QAction::triggered, this, &MainWindow::play_snake);
     connect(ui->action_propos_de_Cellulut, &QAction::triggered, this, [this](bool)
-    {
-        QMessageBox::about(this, "À propos de Cellulut",
-                           "Projet de C++ réalisé dans le cadre de l'UV LO21 de l'UTC.\n\n"
+            {
+                QMessageBox::about(this, "À propos de Cellulut",
+                                   "Projet de C++ réalisé dans le cadre de l'UV LO21 de l'UTC.\n\n"
                                    "Contributeurs : Anthony Noir, Eugène Pin, Merwane Bouri, Arthur Detree, Yann Boucher");
-    });
+            });
     connect(ui->action_propos_de_Qt, &QAction::triggered, this, [this](bool)
-    {
-        QMessageBox::aboutQt(this, "À propos de Qt");
-    });
+            {
+                QMessageBox::aboutQt(this, "À propos de Qt");
+            });
     connect(ui->actionCharger_depuis_une_image, &QAction::triggered, this, [this](bool)
-    {
-        load_from_image();
-    });
+            {
+                load_from_image();
+            });
     connect(ui->border_combo, QOverload<int>::of(&QComboBox::activated), this, &MainWindow::load_boundary_policy);
 
     ui->struct_library->update_cell_pixel_size(ui->grid_view->cell_screen_size());
@@ -647,13 +650,6 @@ QJsonObject MainWindow::default_configuration() const
     return doc.object();
 }
 
-// Décommenter pour activer le son sur win
-//#define BAD_APPLE_WIN
-
-#if defined(BAD_APPLE_WIN)
-#include <windows.h>
-#endif
-
 void MainWindow::play_bad_apple()
 {
     static QJsonArray bad_apple_frame_list;
@@ -683,37 +679,37 @@ void MainWindow::play_bad_apple()
     if (!bad_apple_connected)
     {
         bad_apple_timer.callOnTimeout([this]
-        {
+                                      {
 #ifdef BAD_APPLE_AUDIO
-            unsigned frame_idx = bad_apple_player.position()/(1000.f/30);
+                                          unsigned frame_idx = bad_apple_player.position()/(1000.f/30);
 #else
-            unsigned frame_idx = bad_apple_elapsed.elapsed()/(1000.f/30);
+                                          unsigned frame_idx = bad_apple_elapsed.elapsed()/(1000.f/30);
 #endif
-            if ((int)frame_idx >= bad_apple_frame_list.size())
-            {
-                bad_apple_timer.stop();
-                return;
-            }
+                                          if ((int)frame_idx >= bad_apple_frame_list.size())
+                                          {
+                                              bad_apple_timer.stop();
+                                              return;
+                                          }
 
-            Grid grid(120, 160);
+                                          Grid grid(120, 160);
 
-            QJsonObject frame = bad_apple_frame_list[frame_idx].toObject();
+                                          QJsonObject frame = bad_apple_frame_list[frame_idx].toObject();
 
-            Coord origin;
-            origin.x = frame.value("left").toInt();
-            origin.y = frame.value("top").toInt();
+                                          Coord origin;
+                                          origin.x = frame.value("left").toInt();
+                                          origin.y = frame.value("top").toInt();
 
-            RLEStructureReader reader(frame.value("data").toString().toStdString());
-            Structure s = reader.read_structure();
-            s.top_left = origin;
+                                          RLEStructureReader reader(frame.value("data").toString().toStdString());
+                                          Structure s = reader.read_structure();
+                                          s.top_left = origin;
 
-            for (auto cell : s)
-            {
-                grid.set_cell(cell.first + s.top_left, cell.second);
-            }
+                                          for (auto cell : s)
+                                          {
+                                              grid.set_cell(cell.first + s.top_left, cell.second);
+                                          }
 
-            ui->grid_view->copy_grid(grid);
-        });
+                                          ui->grid_view->copy_grid(grid);
+                                      });
     };
 
     // On coupe la simulation si elle est en train de s'exécuter
@@ -734,6 +730,124 @@ void MainWindow::play_bad_apple()
     statusBar()->showMessage("Original : \"Bad Apple!!\" feat. Nomico by Alstroemeria Records", 60000);
 }
 
+void MainWindow::play_snake()
+{
+    static QTimer snake_timer;
+    static Coord snake_dir;
+    static std::list<Coord> snake_body;
+    static bool snake_connected = false;
+
+    statusBar()->showMessage("Controls : ZQSD", 60000);
+
+    Alphabet alph;
+    alph.newEtat(state{stateColor{0, 0, 0}, "Snake"});
+    alph.newEtat(state{stateColor{255, 0, 0}, "Apple"});
+
+    ui->grid_view->set_alphabet(alph);
+
+    snake_body.clear();
+    snake_dir = {+1, 0};
+
+    on_pushButton_clicked(); // reset la grille
+
+    static auto restore = [&]
+    {
+        ui_update_alphabet(simulation.getAlphabet());
+        snake_timer.stop();
+        on_pushButton_clicked(); // reset la grille
+    };
+
+    static auto spawn_apple = [&]
+    {
+        unsigned attempt_limit = 10000;
+        while (attempt_limit>0)
+        {
+            --attempt_limit;
+            int rand_x = rand() % ui->grid_view->get_grid().get_col();
+            int rand_y = rand() % ui->grid_view->get_grid().get_rows();
+            Coord c = {rand_x, rand_y};
+            Grid g = ui->grid_view->get_grid();
+            if (g.get_state(c) != 0)
+                continue;
+
+            g.set_cell(c, 2);
+            ui->grid_view->copy_grid(g);
+            break;
+        }
+        if (attempt_limit <= 0) // plus possible de placer de pomme
+        {
+            restore();
+            return;
+        }
+    };
+
+    static auto advance_snake = [&](bool expand)
+    {
+        Coord next = snake_body.back() + snake_dir;
+        snake_body.push_back(next);
+        Grid g = ui->grid_view->get_grid();
+        if (g.get_state(snake_body.back()) == 1 ||
+            next.x < 0 || next.y < 0 ||
+            next.x >= (int)g.get_col() || next.y >= (int)g.get_rows())
+        {
+            restore();
+            return;
+        }
+        // manger la pomme
+        else if (g.get_state(snake_body.back()) == 2)
+        {
+            expand = true;
+            spawn_apple();
+        }
+        g = ui->grid_view->get_grid();
+        g.set_cell(snake_body.back(), 1);
+        ui->grid_view->copy_grid(g);
+
+        auto tail = snake_body.front();
+        if (!expand)
+        {
+            snake_body.pop_front();
+            Grid g = ui->grid_view->get_grid();
+            g.set_cell(tail, 0);
+            ui->grid_view->copy_grid(g);
+        }
+    };
+
+    Coord start = {3, 1};
+    snake_body.push_back(start);
+    Grid g = ui->grid_view->get_grid();
+    g.set_cell(start, 1);
+    ui->grid_view->copy_grid(g);
+
+    advance_snake(true);
+    advance_snake(true);
+    spawn_apple();
+
+    // On coupe la simulation si elle est en train de s'exécuter
+    if (timer->isActive())
+    {
+        on_playPauseButton_clicked();
+    }
+
+    if (!snake_connected)
+    {
+        snake_timer.callOnTimeout([this]
+                                  {
+                                      if (m_arrow_key_state[0] && snake_dir != Coord{+1, 0})
+                                          snake_dir = {-1, 0};
+                                      else if (m_arrow_key_state[1] && snake_dir != Coord{0, -1})
+                                          snake_dir = {0, +1};
+                                      else if (m_arrow_key_state[2] && snake_dir != Coord{-1, 0})
+                                          snake_dir = {+1, 0};
+                                      else if (m_arrow_key_state[3] && snake_dir != Coord{0, +1})
+                                          snake_dir = {0, -1};
+                                      advance_snake(false);
+                                  });
+        snake_connected = true;
+    }
+    snake_timer.start(100);
+}
+
 void MainWindow::closeEvent(QCloseEvent *e)
 {
     // Sauvegarder l'état actuel de l'application
@@ -773,6 +887,32 @@ void MainWindow::closeEvent(QCloseEvent *e)
     QMainWindow::closeEvent(e);
 }
 
+void MainWindow::keyPressEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Q)
+        m_arrow_key_state[0] = true;
+    if (event->key() == Qt::Key_S)
+        m_arrow_key_state[1] = true;
+    if (event->key() == Qt::Key_D)
+        m_arrow_key_state[2] = true;
+    if (event->key() == Qt::Key_Z)
+        m_arrow_key_state[3] = true;
+    QMainWindow::keyPressEvent(event);
+}
+
+void MainWindow::keyReleaseEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Q)
+        m_arrow_key_state[0] = false;
+    if (event->key() == Qt::Key_S)
+        m_arrow_key_state[1] = false;
+    if (event->key() == Qt::Key_D)
+        m_arrow_key_state[2] = false;
+    if (event->key() == Qt::Key_Z)
+        m_arrow_key_state[3] = false;
+    QMainWindow::keyReleaseEvent(event);
+}
+
 void MainWindow::on_saveRuleButton_clicked()
 {
     save_model();