diff --git a/src/dude.cpp b/src/dude.cpp index ac17b8b..3422d56 100644 --- a/src/dude.cpp +++ b/src/dude.cpp @@ -11,6 +11,11 @@ Dude::Dude(const Coord &_pos, Map *_map, int &_team) : m_inventory(EMPTY) { std::memset(&m_memory, 0, DUDE_MEMORY_SIZE); + m_under = p_map->getPixel(m_pos).type; + if(isResource(m_under)) + m_underResCount = p_map->getPixel(m_pos).data.nbRes; + p_map->getPixel(m_pos).type = DUDE; + p_map->getPixel(m_pos).data.dudePtr = this; } char* Dude::getMemory() @@ -20,9 +25,19 @@ char* Dude::getMemory() void Dude::move(Dir d) { + p_map->getPixel(m_pos).type = m_under; + if(isResource(m_under)) + p_map->getPixel(m_pos).data.nbRes = m_underResCount; + p_map->getPixel(m_pos).data.dudePtr = NULL; + m_pos += Coord(d); - m_pos.x %= p_map->getWidth(); - m_pos.y %= p_map->getHeight(); + + m_under = p_map->getPixel(m_pos).type; + if(isResource(m_under)) + m_underResCount = p_map->getPixel(m_pos).data.nbRes; + p_map->getPixel(m_pos).type = DUDE; + p_map->getPixel(m_pos).data.dudePtr = this; + p_map->toreillerLoop(m_pos); } void Dude::receiveComData(const Com &comData) diff --git a/src/dude.h b/src/dude.h index f600a2d..8515eb1 100644 --- a/src/dude.h +++ b/src/dude.h @@ -12,6 +12,8 @@ private: bool m_dead; bool m_success; PixelType m_inventory; + PixelType m_under; + int m_underResCount; char m_memory[DUDE_MEMORY_SIZE]; Com m_comData; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 0f3d69f..e3b99a0 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -10,10 +10,18 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - m_simSpeed(500) + p_simu(NULL), + m_simSpeed(500), + m_simSpeedChanged(false), + m_paused(false) { ui->setupUi(this); + m_simuTimer = new QTimer(this); + connect(m_simuTimer,SIGNAL(timeout()),this, SLOT(updateSimu())); + m_simuTimer->start(m_simSpeed); connect(ui->startButton, SIGNAL(pressed()), this, SLOT(openSimuDialog())); + connect(ui->simSpeedSlider, SIGNAL(valueChanged(int)), this, SLOT(changeSimSpeed(int))); + connect(ui->pauseButton, SIGNAL(toggled(bool)), this, SLOT(pauseSimu(bool))); } MainWindow::~MainWindow() @@ -23,26 +31,62 @@ MainWindow::~MainWindow() void MainWindow::openSimuDialog() { + pauseSimu(true); SimulationDialog *dialog = new SimulationDialog(this); dialog->setWindowTitle("Starting a new Simulation"); connect(dialog, SIGNAL(sendError(QString, int)), ui->statusBar, SLOT(showMessage(QString, int))); int ret = dialog->exec(); if(ret == QDialog::Accepted) { + if(p_simu != NULL) + delete p_simu; p_simu = dialog->getSimulation(); ui->drawWidget->startSimulation(p_simu->getMap()); - QTimer *timer = new QTimer(this); - connect(timer,SIGNAL(timeout()),this, SLOT(updateSimu())); - timer->start(m_simSpeed); m_date = 0; } + pauseSimu(false); +} + +void MainWindow::changeSimSpeed(int newSpeed) +{ + m_simSpeedChanged = true; + m_simSpeed = newSpeed; } void MainWindow::updateSimu() { - p_simu->update(); - ui->dateLabel->setText(QString::number(++m_date)); - ui->populationLabel->setText(QString::number(p_simu->getPopulation())); - ui->drawWidget->updateDudesBehavior(); - ui->drawWidget->repaint(); + if(!m_paused) + { + if(p_simu != NULL) + { + p_simu->update(); + ui->dateLabel->setText(QString::number(++m_date)); + ui->populationLabel->setText(QString::number(p_simu->getPopulation())); + ui->drawWidget->updateDudesBehavior(); + ui->drawWidget->repaint(); + } + if(m_simSpeedChanged) + { + m_simuTimer->stop(); + m_simuTimer->start(m_simSpeed); + m_simSpeedChanged = false; + } + } +} + +void MainWindow::pauseSimu(bool pause) +{ + m_paused = pause; + ui->pauseButton->setChecked(m_paused); + if(m_paused) + { + m_simuTimer->stop(); + ui->pauseButton->setText("RESUME"); + } + else + { + m_simuTimer->start(m_simSpeed); + ui->pauseButton->setText("PAUSE"); + } + m_simSpeedChanged = false; } diff --git a/src/mainwindow.h b/src/mainwindow.h index e8a416a..7f85e8a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -19,13 +19,18 @@ public: private: Ui::MainWindow *ui; + QTimer *m_simuTimer; Simulation* p_simu; int m_date; int m_simSpeed; + bool m_simSpeedChanged; + bool m_paused; private slots: void openSimuDialog(); + void changeSimSpeed(int newSpeed); void updateSimu(); + void pauseSimu(bool); }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 1730be6..5f678de 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -41,13 +41,15 @@ 0 0 744 - 20 + 18 Menu + + @@ -84,7 +86,7 @@ 0 0 260 - 344 + 346 @@ -99,7 +101,7 @@ - + false @@ -116,7 +118,7 @@ - + false @@ -133,13 +135,43 @@ - + - false + true + + + 100 + + + 2000 + + + 100 + + + 100 + + + 500 + + + 500 Qt::Horizontal + + false + + + false + + + QSlider::TicksBelow + + + 100 + @@ -163,7 +195,7 @@ 0 0 260 - 344 + 346 @@ -222,6 +254,9 @@ + + Qt::NoFocus + START @@ -229,6 +264,12 @@ + + false + + + Qt::NoFocus + STOP @@ -236,9 +277,18 @@ + + Qt::NoFocus + PAUSE + + Space + + + true + @@ -253,6 +303,17 @@ Quit + + + true + + + true + + + Control Panel + + @@ -280,5 +341,37 @@ + + actionControl_Panel + toggled(bool) + dockWidget + setVisible(bool) + + + -1 + -1 + + + 129 + 242 + + + + + dockWidget + visibilityChanged(bool) + actionControl_Panel + setChecked(bool) + + + 129 + 242 + + + -1 + -1 + + + diff --git a/src/map.h b/src/map.h index 0ff3fb7..ab47b65 100644 --- a/src/map.h +++ b/src/map.h @@ -9,9 +9,10 @@ class Dude; struct Pixel { union PixelData { - int nbRes; - int teamId; - Dude* dudePtr; + int nbRes; // RESOURCES + char *knowledge; // LIBRARY + int teamId; // SPAWN + Dude* dudePtr; // DUDE }; PixelType type; @@ -63,6 +64,21 @@ public: { return m_map + m_height*i; } Pixel &operator[](const Coord &c) { return m_map[m_height*c.x + c.y]; } + + Coord &toreillerLoop(Coord &c) + { + // this is the shader implementation of the toreiller + Coord nbRevolutions(c.x/m_width, c.y/m_height); + if(abs(nbRevolutions.y % 2)) + { + c.x += m_width/2; + nbRevolutions.x = c.x/m_width; + } + c -= Coord(nbRevolutions.x*m_width, nbRevolutions.y*m_height); + return c; + } + Coord toreillerLoop(const Coord &c) + { Coord myCoord = c; toreillerLoop(myCoord); return myCoord; } }; /** diff --git a/src/mapscene.cpp b/src/mapscene.cpp index ea4850f..da9419e 100644 --- a/src/mapscene.cpp +++ b/src/mapscene.cpp @@ -44,12 +44,11 @@ MapScene::~MapScene() void MapScene::updatePixel(const Coord &c) { QMutexLocker lock(&m_mutex); - auto it = m_updatedCoordMap.find(c); - if(it != m_updatedCoordMap.end()) - m_pixels[it->second].color = getColor(getPixel(c)); + if(m_updatedCoordMap.count(c)) + m_pixels[m_updatedCoordMap[c]].color = getColor(getPixel(c)); else { - it->second = m_pixels.size(); + m_updatedCoordMap[c] = m_pixels.size(); m_pixels.push_back(Pix(glm::vec2(c.x+0.5f, c.y+0.5f), getColor(getPixel(c)))); } } diff --git a/src/pixeltype.cpp b/src/pixeltype.cpp index ce5ab4d..cb54641 100644 --- a/src/pixeltype.cpp +++ b/src/pixeltype.cpp @@ -3,7 +3,17 @@ bool isWalkable(PixelType target){ return target != WALL && target != ROCK && target != BEDROCK - && target != IRON_ORE && target != TREE && target != LIBRARY; + && target != IRON_ORE && target != TREE && target != LIBRARY + && target != DUDE && target != SPAWN; +} + +bool isResource(PixelType target) +{ + return target == FOOD + || target == WOOD + || target == STONE + || target == IRON + || target == SWORD; } bool isDestroyable(PixelType target){ diff --git a/src/pixeltype.h b/src/pixeltype.h index 604afa1..30a0453 100644 --- a/src/pixeltype.h +++ b/src/pixeltype.h @@ -12,5 +12,6 @@ enum PixelType { //we might have to place these function elsewhere ? bool isWalkable(PixelType target); bool isDestroyable(PixelType target); +bool isResource(PixelType target); #endif // PIXELTYPE_H diff --git a/src/simulation.cpp b/src/simulation.cpp index 1708507..aa7522e 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -25,42 +25,46 @@ void Simulation::update() std::random_shuffle(m_dudes.begin(), m_dudes.end()); for (int i=0; igetTeam()].update(dude); //get action for this dude from behavior function in team - handleAction(action, dude); + Action *action = m_teams[dude->getTeam()].update(dude); //get action for this dude from behavior function in team + handleAction(*action, dude); + delete action; } // for each team, spawn dude if condition met for(int i=0; iteam(i) + Coord(Dir(rand()%4)); - Dude *dude = new Dude(spawnPos,p_map,i); - (*p_map)[spawnPos].data.dudePtr = dude; - p_map->updatePixel(spawnPos); - m_dudes.push_back(dude); + if(isWalkable(p_map->getPixel(spawnPos).type)) + { + Dude *dude = new Dude(spawnPos,p_map,i); + (*p_map)[spawnPos].data.dudePtr = dude; + p_map->updatePixel(spawnPos); + m_dudes.push_back(dude); + }/* + else + // TODO delay the spawning + */ } } } -// TODO finish conversion of handleAction() -void Simulation::handleAction(Action *action, Dude *dude){ +void Simulation::handleAction(const Action &action, Dude *dude){ + + // initialisation Coord currentPos(dude->getPos()); - Coord targetPos(currentPos + Coord(action->dir)); - Pixel source = (*p_map)[currentPos]; - Pixel target = (*p_map)[targetPos]; - Dude* targetDude; + Coord targetPos = p_map->toreillerLoop(currentPos + Coord(action.dir)); + Pixel &source = p_map->getPixel(currentPos); + Pixel &target = p_map->getPixel(targetPos); dude->setSuccess(false); - if(action == NULL) return; - switch(action->type){ - case Action::MOVE: - if (isWalkable(target.type) && target.data.dudePtr == NULL){ - source.data.dudePtr = NULL; - target.data.dudePtr = dude; - dude->move(action->dir); + + switch(action.type){ + case Action::MOVE: // DONE + if(isWalkable(target.type)){ + dude->move(action.dir); p_map->updatePixel(currentPos); p_map->updatePixel(targetPos); - std::cout << "Moving to [" << targetPos.x << "," << targetPos.y << "]"<< std::endl; + dude->setSuccess(true); } break; case Action::ATTACK: @@ -167,22 +171,23 @@ void Simulation::handleAction(Action *action, Dude *dude){ case Action::COMMUNICATE: switch(target.type){ case DUDE: - action->com_data.flag = (action->dir+2)%4; - // TODO : find a way to get targetDude - //targetDude = + { + // WTF ? -> action.com_data.flag = (action.dir+2)%4; + Dude *targetDude = target.data.dudePtr; if(targetDude->getCom().data == NULL){ - targetDude->receiveComData(action->com_data); + targetDude->receiveComData(action.com_data); dude->setSuccess(true); }else dude->setSuccess(false); break; + } case LIBRARY: - if(action->com_data.flag & Com::READ) + if(action.com_data.flag & Com::READ) { if(dude->getCom().data == NULL) { - action->com_data.flag = action->dir; - dude->receiveComData(action->com_data); + // WTF ? -> action.com_data.flag = action.dir; + dude->receiveComData(action.com_data); // TODO: understand what the fuck this line is doing //memcpy(dude->getCom() + sizeof(int), target.data.knowledge + (action->com_data.flag | 3), COM_SIZE); } @@ -199,7 +204,6 @@ void Simulation::handleAction(Action *action, Dude *dude){ } break; default: - dude->setSuccess(false); break; } } diff --git a/src/simulation.h b/src/simulation.h index e7927ff..6ae42a1 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -22,7 +22,7 @@ public: * @brief update runs one step of simulation */ void update(); - void handleAction(Action*, Dude* dude); + void handleAction(const Action &action, Dude* dude); }; #endif // SIMULATION_H diff --git a/src/team.cpp b/src/team.cpp index 39813b5..995ee4b 100644 --- a/src/team.cpp +++ b/src/team.cpp @@ -24,6 +24,7 @@ bool Team::updateSpawn() } return false; } + void Team::destroySpawn(){ m_spawnCooldown = 0; m_foodQuantity = 0;