updated interface, simSpeed control and pause is now working, updateing pixel position after move also works

This commit is contained in:
Anselme 2016-05-27 11:58:28 +02:00
parent 49d1ffb0c4
commit 67c18703a1
12 changed files with 247 additions and 57 deletions

View File

@ -11,6 +11,11 @@ Dude::Dude(const Coord &_pos, Map *_map, int &_team) :
m_inventory(EMPTY) m_inventory(EMPTY)
{ {
std::memset(&m_memory, 0, DUDE_MEMORY_SIZE); 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() char* Dude::getMemory()
@ -20,9 +25,19 @@ char* Dude::getMemory()
void Dude::move(Dir d) 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 += 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) void Dude::receiveComData(const Com &comData)

View File

@ -12,6 +12,8 @@ private:
bool m_dead; bool m_dead;
bool m_success; bool m_success;
PixelType m_inventory; PixelType m_inventory;
PixelType m_under;
int m_underResCount;
char m_memory[DUDE_MEMORY_SIZE]; char m_memory[DUDE_MEMORY_SIZE];
Com m_comData; Com m_comData;

View File

@ -10,10 +10,18 @@
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow), ui(new Ui::MainWindow),
m_simSpeed(500) p_simu(NULL),
m_simSpeed(500),
m_simSpeedChanged(false),
m_paused(false)
{ {
ui->setupUi(this); 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->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() MainWindow::~MainWindow()
@ -23,26 +31,62 @@ MainWindow::~MainWindow()
void MainWindow::openSimuDialog() void MainWindow::openSimuDialog()
{ {
pauseSimu(true);
SimulationDialog *dialog = new SimulationDialog(this); SimulationDialog *dialog = new SimulationDialog(this);
dialog->setWindowTitle("Starting a new Simulation"); dialog->setWindowTitle("Starting a new Simulation");
connect(dialog, SIGNAL(sendError(QString, int)), ui->statusBar, SLOT(showMessage(QString, int))); connect(dialog, SIGNAL(sendError(QString, int)), ui->statusBar, SLOT(showMessage(QString, int)));
int ret = dialog->exec(); int ret = dialog->exec();
if(ret == QDialog::Accepted) if(ret == QDialog::Accepted)
{ {
if(p_simu != NULL)
delete p_simu;
p_simu = dialog->getSimulation(); p_simu = dialog->getSimulation();
ui->drawWidget->startSimulation(p_simu->getMap()); 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; m_date = 0;
} }
pauseSimu(false);
}
void MainWindow::changeSimSpeed(int newSpeed)
{
m_simSpeedChanged = true;
m_simSpeed = newSpeed;
} }
void MainWindow::updateSimu() void MainWindow::updateSimu()
{ {
p_simu->update(); if(!m_paused)
ui->dateLabel->setText(QString::number(++m_date)); {
ui->populationLabel->setText(QString::number(p_simu->getPopulation())); if(p_simu != NULL)
ui->drawWidget->updateDudesBehavior(); {
ui->drawWidget->repaint(); 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;
} }

View File

@ -19,13 +19,18 @@ public:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
QTimer *m_simuTimer;
Simulation* p_simu; Simulation* p_simu;
int m_date; int m_date;
int m_simSpeed; int m_simSpeed;
bool m_simSpeedChanged;
bool m_paused;
private slots: private slots:
void openSimuDialog(); void openSimuDialog();
void changeSimSpeed(int newSpeed);
void updateSimu(); void updateSimu();
void pauseSimu(bool);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -41,13 +41,15 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>744</width> <width>744</width>
<height>20</height> <height>18</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuMenu"> <widget class="QMenu" name="menuMenu">
<property name="title"> <property name="title">
<string>Menu</string> <string>Menu</string>
</property> </property>
<addaction name="actionControl_Panel"/>
<addaction name="separator"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
</widget> </widget>
<addaction name="menuMenu"/> <addaction name="menuMenu"/>
@ -84,7 +86,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>260</width> <width>260</width>
<height>344</height> <height>346</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -99,7 +101,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSlider" name="horizontalSlider"> <widget class="QSlider" name="flatSphereSlider">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -116,7 +118,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSlider" name="horizontalSlider_2"> <widget class="QSlider" name="surfaceRatioSlider">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -133,13 +135,43 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QSlider" name="horizontalSlider_3"> <widget class="QSlider" name="simSpeedSlider">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>true</bool>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>2000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="pageStep">
<number>100</number>
</property>
<property name="value">
<number>500</number>
</property>
<property name="sliderPosition">
<number>500</number>
</property> </property>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="invertedAppearance">
<bool>false</bool>
</property>
<property name="invertedControls">
<bool>false</bool>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBelow</enum>
</property>
<property name="tickInterval">
<number>100</number>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -163,7 +195,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>260</width> <width>260</width>
<height>344</height> <height>346</height>
</rect> </rect>
</property> </property>
<attribute name="label"> <attribute name="label">
@ -222,6 +254,9 @@
</property> </property>
<item> <item>
<widget class="QPushButton" name="startButton"> <widget class="QPushButton" name="startButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string>START</string> <string>START</string>
</property> </property>
@ -229,6 +264,12 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="stopButton"> <widget class="QPushButton" name="stopButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string>STOP</string> <string>STOP</string>
</property> </property>
@ -236,9 +277,18 @@
</item> </item>
<item> <item>
<widget class="QPushButton" name="pauseButton"> <widget class="QPushButton" name="pauseButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text"> <property name="text">
<string>PAUSE</string> <string>PAUSE</string>
</property> </property>
<property name="shortcut">
<string>Space</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
</layout> </layout>
@ -253,6 +303,17 @@
<string>Quit</string> <string>Quit</string>
</property> </property>
</action> </action>
<action name="actionControl_Panel">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Control Panel</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>
@ -280,5 +341,37 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>actionControl_Panel</sender>
<signal>toggled(bool)</signal>
<receiver>dockWidget</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>-1</x>
<y>-1</y>
</hint>
<hint type="destinationlabel">
<x>129</x>
<y>242</y>
</hint>
</hints>
</connection>
<connection>
<sender>dockWidget</sender>
<signal>visibilityChanged(bool)</signal>
<receiver>actionControl_Panel</receiver>
<slot>setChecked(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>129</x>
<y>242</y>
</hint>
<hint type="destinationlabel">
<x>-1</x>
<y>-1</y>
</hint>
</hints>
</connection>
</connections> </connections>
</ui> </ui>

View File

@ -9,9 +9,10 @@ class Dude;
struct Pixel struct Pixel
{ {
union PixelData { union PixelData {
int nbRes; int nbRes; // RESOURCES
int teamId; char *knowledge; // LIBRARY
Dude* dudePtr; int teamId; // SPAWN
Dude* dudePtr; // DUDE
}; };
PixelType type; PixelType type;
@ -63,6 +64,21 @@ public:
{ return m_map + m_height*i; } { return m_map + m_height*i; }
Pixel &operator[](const Coord &c) Pixel &operator[](const Coord &c)
{ return m_map[m_height*c.x + c.y]; } { 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; }
}; };
/** /**

View File

@ -44,12 +44,11 @@ MapScene::~MapScene()
void MapScene::updatePixel(const Coord &c) void MapScene::updatePixel(const Coord &c)
{ {
QMutexLocker lock(&m_mutex); QMutexLocker lock(&m_mutex);
auto it = m_updatedCoordMap.find(c); if(m_updatedCoordMap.count(c))
if(it != m_updatedCoordMap.end()) m_pixels[m_updatedCoordMap[c]].color = getColor(getPixel(c));
m_pixels[it->second].color = getColor(getPixel(c));
else 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)))); m_pixels.push_back(Pix(glm::vec2(c.x+0.5f, c.y+0.5f), getColor(getPixel(c))));
} }
} }

View File

@ -3,7 +3,17 @@
bool isWalkable(PixelType target){ bool isWalkable(PixelType target){
return target != WALL && target != ROCK && target != BEDROCK 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){ bool isDestroyable(PixelType target){

View File

@ -12,5 +12,6 @@ enum PixelType {
//we might have to place these function elsewhere ? //we might have to place these function elsewhere ?
bool isWalkable(PixelType target); bool isWalkable(PixelType target);
bool isDestroyable(PixelType target); bool isDestroyable(PixelType target);
bool isResource(PixelType target);
#endif // PIXELTYPE_H #endif // PIXELTYPE_H

View File

@ -25,42 +25,46 @@ void Simulation::update()
std::random_shuffle(m_dudes.begin(), m_dudes.end()); std::random_shuffle(m_dudes.begin(), m_dudes.end());
for (int i=0; i<m_dudes.size(); ++i){ for (int i=0; i<m_dudes.size(); ++i){
Dude *dude = m_dudes[i]; Dude *dude = m_dudes[i];
auto action = m_teams[dude->getTeam()].update(dude); //get action for this dude from behavior function in team Action *action = m_teams[dude->getTeam()].update(dude); //get action for this dude from behavior function in team
handleAction(action, dude); handleAction(*action, dude);
delete action;
} }
// for each team, spawn dude if condition met // for each team, spawn dude if condition met
for(int i=0; i<m_teams.size(); ++i){ for(int i=0; i<m_teams.size(); ++i){
Team &t = m_teams[i]; Team &t = m_teams[i];
if (t.updateSpawn()) if(t.updateSpawn())
{ {
//TODO: check if target pixel is walkable and has no dude
Coord spawnPos = p_map->team(i) + Coord(Dir(rand()%4)); Coord spawnPos = p_map->team(i) + Coord(Dir(rand()%4));
Dude *dude = new Dude(spawnPos,p_map,i); if(isWalkable(p_map->getPixel(spawnPos).type))
(*p_map)[spawnPos].data.dudePtr = dude; {
p_map->updatePixel(spawnPos); Dude *dude = new Dude(spawnPos,p_map,i);
m_dudes.push_back(dude); (*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(const Action &action, Dude *dude){
void Simulation::handleAction(Action *action, Dude *dude){
// initialisation
Coord currentPos(dude->getPos()); Coord currentPos(dude->getPos());
Coord targetPos(currentPos + Coord(action->dir)); Coord targetPos = p_map->toreillerLoop(currentPos + Coord(action.dir));
Pixel source = (*p_map)[currentPos]; Pixel &source = p_map->getPixel(currentPos);
Pixel target = (*p_map)[targetPos]; Pixel &target = p_map->getPixel(targetPos);
Dude* targetDude;
dude->setSuccess(false); dude->setSuccess(false);
if(action == NULL) return;
switch(action->type){ switch(action.type){
case Action::MOVE: case Action::MOVE: // DONE
if (isWalkable(target.type) && target.data.dudePtr == NULL){ if(isWalkable(target.type)){
source.data.dudePtr = NULL; dude->move(action.dir);
target.data.dudePtr = dude;
dude->move(action->dir);
p_map->updatePixel(currentPos); p_map->updatePixel(currentPos);
p_map->updatePixel(targetPos); p_map->updatePixel(targetPos);
std::cout << "Moving to [" << targetPos.x << "," << targetPos.y << "]"<< std::endl; dude->setSuccess(true);
} }
break; break;
case Action::ATTACK: case Action::ATTACK:
@ -167,22 +171,23 @@ void Simulation::handleAction(Action *action, Dude *dude){
case Action::COMMUNICATE: case Action::COMMUNICATE:
switch(target.type){ switch(target.type){
case DUDE: case DUDE:
action->com_data.flag = (action->dir+2)%4; {
// TODO : find a way to get targetDude // WTF ? -> action.com_data.flag = (action.dir+2)%4;
//targetDude = Dude *targetDude = target.data.dudePtr;
if(targetDude->getCom().data == NULL){ if(targetDude->getCom().data == NULL){
targetDude->receiveComData(action->com_data); targetDude->receiveComData(action.com_data);
dude->setSuccess(true); dude->setSuccess(true);
}else }else
dude->setSuccess(false); dude->setSuccess(false);
break; break;
}
case LIBRARY: case LIBRARY:
if(action->com_data.flag & Com::READ) if(action.com_data.flag & Com::READ)
{ {
if(dude->getCom().data == NULL) if(dude->getCom().data == NULL)
{ {
action->com_data.flag = action->dir; // WTF ? -> action.com_data.flag = action.dir;
dude->receiveComData(action->com_data); dude->receiveComData(action.com_data);
// TODO: understand what the fuck this line is doing // TODO: understand what the fuck this line is doing
//memcpy(dude->getCom() + sizeof(int), target.data.knowledge + (action->com_data.flag | 3), COM_SIZE); //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; break;
default: default:
dude->setSuccess(false);
break; break;
} }
} }

View File

@ -22,7 +22,7 @@ public:
* @brief update runs one step of simulation * @brief update runs one step of simulation
*/ */
void update(); void update();
void handleAction(Action*, Dude* dude); void handleAction(const Action &action, Dude* dude);
}; };
#endif // SIMULATION_H #endif // SIMULATION_H

View File

@ -24,6 +24,7 @@ bool Team::updateSpawn()
} }
return false; return false;
} }
void Team::destroySpawn(){ void Team::destroySpawn(){
m_spawnCooldown = 0; m_spawnCooldown = 0;
m_foodQuantity = 0; m_foodQuantity = 0;