00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "simulation.hpp"
00022 #include <iostream>
00023 #include <map>
00024
00025 using namespace std;
00026
00028
00035 Simulation::Simulation(SimulationView *view, SimulationManager *controller, Grid initialLayout, list<Rule> *rules, list<ForbiddenPattern> *patterns)
00036 {
00037 finalLayouts = new list<simulationStep>;
00038 patternsSimulated = new list<Grid>;
00039 patternsToSimulate = new list<simulationStep>;
00040 forbiddenPatternsFound = new list<simulationStep>;
00041 cycles = new list<simulationStep>;
00042 simulationStep s;
00043 s.space = initialLayout;
00044 patternsToSimulate->push_back(s);
00045 this->rules = rules;
00046 this->patterns = patterns;
00047 this->view = view;
00048 this->controller = controller;
00049 view->setGrid(initialLayout, true);
00050 view->Show(true);
00051 finished = false;
00052 simulating = false;
00053 stillRows = true;
00054 }
00055
00056
00058 Simulation::~Simulation()
00059 {
00060 }
00061
00062
00064
00070 list<coordinate> Simulation::findRule(Grid layout, Rule rule)
00071 {
00072 list<coordinate> result;
00073 for (int i = 0; i < layout.getWidth(); i++)
00074 {
00075 for (int j = 0; j < layout.getHeight(); j++)
00076 {
00077 coordinate c;
00078 c.x = i;
00079 c.y = j;
00080 if (ruleApplicable(layout, c, rule))
00081 {
00082 result.push_back(c);
00083
00084 }
00085 }
00086 }
00087 return result;
00088 }
00089
00090
00092
00098 list<coordinate> Simulation::findPattern(Grid layout, ForbiddenPattern pattern)
00099 {
00100 list<coordinate> result;
00101 for (int i = 0; i < layout.getWidth(); i++)
00102 {
00103 for (int j = 0; j < layout.getHeight(); j++)
00104 {
00105 coordinate c;
00106 c.x = i;
00107 c.y = j;
00108 if (patternApplicable(layout, c, pattern))
00109 {
00110 result.push_back(c);
00111
00112 }
00113 }
00114 }
00115 return result;
00116 }
00117
00118
00120
00126 Grid Simulation::applyRule(Grid layout, Rule rule, coordinate position)
00127 {
00128
00129 Grid result(layout);
00130 for (int i = 0; i < rule.getWidth(); i++)
00131 {
00132 for (int j = 0; j < rule.getHeight(); j++)
00133 {
00134 if (rule.getFinalGrid()(i, j) != nDONTCARE)
00135 {
00136
00137 if ((rule.getInitialGrid()(i, j) == nDISABLED) && (layout(position.x + i, position.y + j) == nDONTCARE))
00138 {
00139 result(position.x + i, position.y + j) = nDONTCARE;
00140 }
00141 else
00142 {
00143 result(position.x + i, position.y + j) = rule.getFinalGrid()(i, j);
00144 }
00145 }
00146 }
00147 }
00148 return result;
00149 }
00150
00151
00153
00160 bool Simulation::ruleApplicable(Grid layout, coordinate position, Rule rule)
00161 {
00162 if (rule.getWidth() > layout.getWidth() - position.x)
00163 {
00164 return false;
00165 }
00166 if (rule.getHeight() > layout.getHeight() - position.y)
00167 {
00168 return false;
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 for (int i = 0; i < rule.getWidth(); i++)
00178 {
00179 for (int j = 0; j < rule.getHeight(); j++)
00180 {
00181
00182 if (rule.getInitialGrid()(i, j) == nENABLED)
00183 {
00184 if (layout(position.x + i, position.y + j) != nENABLED)
00185 {
00186 return false;
00187 }
00188 }
00189 else if (rule.getInitialGrid()(i, j) == nDISABLED)
00190 {
00191
00192 if ((layout(position.x + i, position.y + j) != nDISABLED) && (layout(position.x + i, position.y + j) != nDONTCARE))
00193 {
00194 return false;
00195 }
00196 }
00197 }
00198 }
00199 return true;
00200 }
00201
00202
00204
00208 void Simulation::printRule(Rule rule)
00209 {
00210 cout << "Initial" << endl;
00211 for (int i = 0; i < rule.getWidth(); i++)
00212 {
00213 for (int k = 0; k < i; k++)
00214 {
00215 cout << " ";
00216 }
00217 for (int j = 0; j < rule.getHeight(); j++)
00218 {
00219 cout << rule.getInitialGrid()(i, j) << " ";
00220 }
00221 cout << endl;
00222 }
00223
00224 cout << endl;
00225 cout << "Final" << endl;
00226 for (int i = 0; i < rule.getWidth(); i++)
00227 {
00228 for (int k = 0; k < i; k++)
00229 {
00230 cout << " ";
00231 }
00232 for (int j = 0; j < rule.getHeight(); j++)
00233 {
00234 cout << rule.getFinalGrid()(i, j) << " ";
00235 }
00236 cout << endl;
00237 }
00238 }
00239
00240
00242
00246 void Simulation::printLayout(Grid layout)
00247 {
00248 for (int i = 0; i < layout.getWidth(); i++)
00249 {
00250 for (int k = 0; k < i; k++)
00251 {
00252 cout << " ";
00253 }
00254 for (int j = 0; j < layout.getHeight(); j++)
00255 {
00256 cout << layout(i, j) << " ";
00257 }
00258 cout << endl;
00259 }
00260 }
00261
00262
00264
00269 bool Simulation::find(Grid initialLayout, list<Grid> *processedLayouts)
00270 {
00271 for (list<Grid>::iterator i = processedLayouts->begin(); i != processedLayouts->end(); i++)
00272 {
00273 if (initialLayout == (*i))
00274 {
00275 return true;
00276 }
00277 }
00278 return false;
00279 }
00280
00281
00283
00289 bool Simulation::patternApplicable(Grid layout, coordinate position, ForbiddenPattern pattern)
00290 {
00291 if (pattern.getWidth() > layout.getWidth() - position.x)
00292 {
00293 return false;
00294 }
00295 if (pattern.getHeight() > layout.getHeight() - position.y)
00296 {
00297 return false;
00298 }
00299
00300 for (int i = 0; i < pattern.getWidth(); i++)
00301 {
00302 for (int j = 0; j < pattern.getHeight(); j++)
00303 {
00304 if (pattern.getGrid()(i, j) == nENABLED)
00305 {
00306 if (layout(position.x + i, position.y + j) != nENABLED)
00307 {
00308 return false;
00309 }
00310 }
00311 else if (pattern.getGrid()(i, j) == nDISABLED)
00312 {
00313 if (layout(position.x + i, position.y + j) != nDISABLED)
00314 {
00315 return false;
00316 }
00317 }
00318 else
00319 {
00320 if (layout(position.x + i, position.y + j) == nNOSPACE)
00321 {
00322 return false;
00323 }
00324 }
00325 }
00326 }
00327 return true;
00328 }
00329
00330
00332
00335 bool Simulation::isFinished()
00336 {
00337 return finished;
00338 }
00339
00340
00341
00342
00343
00345
00355 bool Simulation::nextStep(bool gui)
00356 {
00357
00358 if (simulating)
00359 {
00360 return true;
00361 }
00362 simulating = true;
00363 wxStopWatch sw;
00364 bool result = true;
00365 bool stable = false;
00366 if (!finished)
00367 {
00368
00369
00370 simulationStep s = patternsToSimulate->back();
00371 Grid layout = s.space;
00372
00373
00374 patternsToSimulate->pop_back();
00375 patternsSimulated->push_back(layout);
00376 if (gui)
00377 {
00378 view->setGrid(layout, false);
00379 }
00380
00381
00382 for (list<ForbiddenPattern>::iterator i = patterns->begin(); i != patterns->end(); i++)
00383 {
00384 list<coordinate> tempCoordinates;
00385 wxStopWatch swPattern;
00386 tempCoordinates = findPattern(layout, (*i));
00387 if (gui)
00388 {
00389 view->setInfo(wxString::Format(_("The pattern finding took %ldms to execute"), swPattern.Time()));
00390 }
00391 if (tempCoordinates.size() > 0)
00392 {
00393 if (gui)
00394 {
00395 view->setInfo(wxString::Format(_("Forbidden pattern found at %d, %d"), tempCoordinates.front().x, tempCoordinates.front().y));
00396 }
00397 finished = true;
00398 result = false;
00399 if (gui)
00400 {
00401 updateView();
00402 }
00403 }
00404 }
00405
00406 if (result)
00407 {
00408
00409 list<ruleApplying> rulesToApply;
00410 for (list<Rule>::iterator i = rules->begin(); i != rules->end(); i++)
00411 {
00412 list<coordinate> tempCoordinates;
00413 wxStopWatch swRule;
00414 tempCoordinates = findRule(layout, (*i));
00415 if (gui)
00416 {
00417 view->setInfo(wxString::Format(_("The rule finding took %ldms to execute"), swRule.Time()));
00418 }
00419 if (tempCoordinates.size() > 0)
00420 {
00421 for (list<coordinate>::iterator j = tempCoordinates.begin(); j != tempCoordinates.end(); j++)
00422 {
00423 ruleApplying ruleToApply;
00424 ruleToApply.rule = &(*i);
00425 ruleToApply.c = (*j);
00426 rulesToApply.push_back(ruleToApply);
00427 }
00428 }
00429 }
00430
00431
00432 if (gui)
00433 {
00434 view->setInfo(wxString::Format(_("Number or applicable rules found: %d"), rulesToApply.size()));
00435 }
00436
00437 if (rulesToApply.size() == 0)
00438 {
00439
00440 finalLayouts->push_back(s);
00441 if (gui)
00442 {
00443 view->setInfo(_("Reached stable layout"));
00444 }
00445 result = true;
00446 stable = true;
00447 }
00448 else
00449 {
00450 result = true;
00451
00452
00453 for(list<ruleApplying>::iterator i = rulesToApply.begin(); i != rulesToApply.end(); i++)
00454 {
00455
00456 if (gui)
00457 {
00458 view->setInfo(wxString::Format(_("Applying rule at %d, %d"), (*i).c.x, (*i).c.y));
00459 }
00460 Grid changedLayout = applyRule(layout, *(*i).rule, (*i).c);
00461
00462
00463
00464
00465
00466
00467
00468 if (find(changedLayout, &(s.path)))
00469 {
00470 list<Grid> newList = s.path;
00471 newList.push_back(layout);
00472 simulationStep newStep;
00473 newStep.path = newList;
00474 newStep.space = changedLayout;
00475 cycles->push_back(newStep);
00476 if (gui)
00477 {
00478 view->setInfo(_("Cycle found"));
00479 }
00480 }
00481 if (!find(changedLayout, patternsSimulated))
00482 {
00483 if (gui)
00484 {
00485 view->setInfo(_("Adding the resulting space to the queue to be simulated"));
00486 }
00487 list<Grid> newList = s.path;
00488 newList.push_back(layout);
00489 simulationStep newStep;
00490 newStep.path = newList;
00491 newStep.space = changedLayout;
00492 patternsToSimulate->push_back(newStep);
00493 }
00494 else
00495 {
00496 if (gui)
00497 {
00498 view->setInfo(_("The resulting space has been already simulated"));
00499 }
00500 }
00501 }
00502 result = true;
00503 }
00504 }
00505 else
00506 {
00507 forbiddenPatternsFound->push_back(s);
00508 controller->finishedRow();
00509 }
00510
00511
00512
00513
00514
00515 if (patternsToSimulate->empty())
00516 {
00517 if (gui)
00518 {
00519 view->setInfo(_("No more spaces to simulate"));
00520 }
00521 finished = true;
00522 result = true;
00523 controller->finishedRow();
00524 if (gui)
00525 {
00526 updateView();
00527 }
00528 }
00529 else
00530 {
00531 if (stable)
00532 {
00533 if (gui)
00534 {
00535 view->setInfo(_("Backtracking to a previous applied rule"));
00536 }
00537 }
00538 }
00539 }
00540 else
00541 {
00542 result = true;
00543 }
00544 if (gui)
00545 {
00546 view->setInfo(wxString::Format(_("The simulation step took %ldms to execute"), sw.Time()));
00547 }
00548 simulating = false;
00549 return result;
00550 }
00551
00552
00554
00558 void Simulation::updateView()
00559 {
00560 if (finished)
00561 {
00562 if (controller->nextRow())
00563 {
00564 view->setResults(false);
00565 view->setNextRow(true);
00566 view->enableSimulation(false);
00567 }
00568 else
00569 {
00570 view->setResults(true);
00571 view->setNextRow(false);
00572 view->enableSimulation(false);
00573 }
00574 }
00575 }
00576
00577
00579 void Simulation::nextRow()
00580 {
00581 if (controller->nextRow())
00582 {
00583 controller->simulateRow();
00584 view->setResults(false);
00585 view->setNextRow(false);
00586 view->enableSimulation(true);
00587 }
00588 else
00589 {
00590 view->setResults(true);
00591 view->setNextRow(false);
00592 view->enableSimulation(true);
00593 }
00594 }
00595
00596
00598 void Simulation::results()
00599 {
00600 controller->results();
00601 }
00602
00603
00605
00610 list<simulationStep> Simulation::getStableLayouts()
00611 {
00612 list<simulationStep> result;
00613 for (list<simulationStep>::iterator i = finalLayouts->begin(); i != finalLayouts->end(); i++)
00614 {
00615 result.push_back((*i));
00616 }
00617 return result;
00618 }
00619
00620
00622
00625 list<Grid> Simulation::getProcessedLayouts()
00626 {
00627 list<Grid> result;
00628 for (list<Grid>::iterator i = patternsSimulated->begin(); i != patternsSimulated->end(); i++)
00629 {
00630 result.push_back((*i));
00631 }
00632 return result;
00633 }
00634
00635
00637
00643 list<simulationStep> Simulation::getForbiddenLayouts()
00644 {
00645 list<simulationStep> result;
00646 for (list<simulationStep>::iterator i = forbiddenPatternsFound->begin(); i != forbiddenPatternsFound->end(); i++)
00647 {
00648 result.push_back((*i));
00649 }
00650 return result;
00651 }
00652
00653
00655
00660 list<simulationStep> Simulation::getCycles()
00661 {
00662 list<simulationStep> result;
00663 for (list<simulationStep>::iterator i = cycles->begin(); i != cycles->end(); i++)
00664 {
00665 result.push_back((*i));
00666 }
00667 return result;
00668 }
00669
00670
00672
00679 void Simulation::resetSimulation(SimulationView *view, SimulationManager *controller, Grid initialLayout, list<Rule> *rules, list<ForbiddenPattern> *patterns)
00680 {
00681
00682 finalLayouts->clear();
00683 patternsSimulated->clear();
00684 patternsToSimulate->clear();
00685 forbiddenPatternsFound->clear();
00686 cycles->clear();
00687 simulationStep s;
00688 s.space = initialLayout;
00689 patternsToSimulate->push_back(s);
00690 this->rules = rules;
00691 this->patterns = patterns;
00692 this->view = view;
00693 this->controller = controller;
00694 view->setGrid(initialLayout, true);
00695 view->Show(true);
00696 finished = false;
00697 stillRows = true;
00698 view->Enable(true);
00699 view->stopSimulation();
00700 }
00701
00702
00703
00705
00709 void Simulation::simulateAll()
00710 {
00711 view->enableSimulation(false);
00712 view->setNextRow(false);
00713 view->setResults(false);
00714 while (stillRows)
00715 {
00716 while (!finished)
00717 {
00718 nextStep(false);
00719 }
00720 if (controller->nextRow())
00721 {
00722 controller->simulateRow();
00723 }
00724 else
00725 {
00726 stillRows = false;
00727 }
00728 }
00729 view->setResults(true);
00730 }