Commit ad5a1153 authored by Yann Boucher's avatar Yann Boucher
Browse files

Snake !

parent c9d19692
Pipeline #79681 passed with stages
in 17 seconds
......@@ -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>
......
......@@ -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
......@@ -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();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment