void MainWindow::dataToPLC() { SerialCommunication link; link.setVars(vars); CommunicationDialog* dialog = new CommunicationDialog; link.setData(lcd->getData()); link.setFont(font); dialog->setMessage("Поиск устройства"); connect(&link,SIGNAL(searchStep(float)),dialog,SLOT(updatePercent(float))); connect(&link,SIGNAL(searchError(QString)),dialog,SLOT(setMessage(QString))); connect(&link,SIGNAL(searchOK(QString)),dialog,SLOT(setMessage(QString))); connect(&link,SIGNAL(writeStep(float)),dialog,SLOT(updatePercent(float))); connect(&link,SIGNAL(writeError(QString)),dialog,SLOT(setMessage(QString))); connect(&link,SIGNAL(writeOK(QString)),dialog,SLOT(setMessage(QString))); link.searchController(); dialog->exec(); delete dialog; }
int KGrEnemy::distanceDown (int x, int y, int deltah) { // When deltah > 0, we want an exit sideways at the hero's level or above. // When deltah <= 0, we can go down any distance (as a last resort). int rungs = -1; int exitRung = 0; bool canGoThru = TRUE; char objType; // If there is a way down at (x,y), return its length, else return zero. // Because rungs == -1, we first check that level y is not blocked here. while (canGoThru) { objType = (*playfield)[x][y + rungs + 1]->whatIam(); switch (objType) { case BRICK: case BETON: case HOLE: // Enemy cannot go DOWN through a hole. case USEDHOLE: if ((deltah > 0) && (rungs <= deltah)) exitRung = rungs; if ((objType == HOLE) && (rungs < 0)) rungs = 0; // Enemy can go SIDEWAYS through a hole. else canGoThru = FALSE; // Cannot go through here. break; case LADDER: case POLE: // Can go through or stop. rungs++; // Add to path length. if ((deltah > 0) && (rungs >= 0)) { // If at or above hero's level, check for an exit from ladder. if ((rungs - 1) <= deltah) { // Maybe can stand on top of ladder and exit L or R. if ((objType == LADDER) && (searchOK (-1, x, y+rungs-1) || searchOK (+1, x, y+rungs-1))) exitRung = rungs - 1; // Maybe can exit L or R from ladder body or pole. if ((rungs <= deltah) && (searchOK (-1, x, y+rungs) || searchOK (+1, x, y+rungs))) exitRung = rungs; } else canGoThru = FALSE; // Should stop at hero's level. } break; default: rungs++; // Can go through. Add to path length. break; } } if (rungs == 1) { for (KGrEnemy *enemy=enemies->first();enemy!=0;enemy=enemies->next()) { if((x*16==enemy->getx()) && (y*16+16==enemy->gety())) rungs = 0; // Pit is blocked. Find another way. } } if (rungs <= 0) return 0; // There is no way down. else if (deltah > 0) return exitRung; // We want to take an exit, if any. else return rungs; // We can go down all the way. }
Direction KGrEnemy::lowSearchDown (int ew, int eh, int hh) { int i, ilen, ipos, j, jlen, jpos, deltah, rungs, path; deltah = hh - eh; // Get distance down to hero's level. // Search for the best way down, right here or on the left. ilen = 0; ipos = -1; i = (willNotFall (ew, eh)) ? ew : -1; rungs = distanceDown (ew, eh, deltah); if (rungs > 0) { ilen = rungs; ipos = ew; } while (i >= 1) { rungs = distanceDown (i - 1, eh, deltah); if (((rungs > 0) && (ilen == 0)) || ((deltah > 0) && (rungs > ilen)) || ((deltah <= 0) && (rungs < ilen) && (rungs != 0))) { ilen = rungs; // This the best way yet. ipos = i - 1; } if (searchOK (-1, i, eh)) i--; // Look further to the left. else i = -1; // Cannot go any further to the left. } // Search for the best way down, on the right. j = ew; jlen = 0; jpos = -1; while (j < FIELDWIDTH) { rungs = distanceDown (j + 1, eh, deltah); if (((rungs > 0) && (jlen == 0)) || ((deltah > 0) && (rungs > jlen)) || ((deltah <= 0) && (rungs < jlen) && (rungs != 0))) { jlen = rungs; // This the best way yet. jpos = j + 1; } if (searchOK (+1, j, eh)) { j++; // Look further to the right. } else j = FIELDWIDTH+1; // Cannot go any further to the right. } if ((ilen == 0) && (jlen == 0)) // Found no way down. return STAND; // Choose a way down to follow. if (ilen == 0) path = jpos; else if (jlen == 0) path = ipos; else if (ilen != jlen) { // If the ways down are not same length, // choose closest to hero's level. if (deltah > 0) { if (jlen > ilen) path = jpos; else path = ipos; } else { if (jlen > ilen) path = ipos; else path = jpos; } } else { // Both ways down are the same length. if ((deltah > 0) && // If both reach the hero's level, (ilen == deltah)) { // choose the closest. if ((ew - ipos) <= (jpos - ew)) path = ipos; else path = jpos; } else path = ipos; // Else, go left or down. } if (path == ew) return DOWN; else if (path < ew) return LEFT; else return RIGHT; }
Direction KGrEnemy::lowSearchUp (int ew, int eh, int hh) { int i, ilen, ipos, j, jlen, jpos, deltah, rungs; deltah = eh - hh; // Get distance up to hero's level. // Search for the best ladder right here or on the left. i = ew; ilen = 0; ipos = -1; while (i >= 1) { rungs = distanceUp (i, eh, deltah); if (rungs > ilen) { ilen = rungs; // This the best yet. ipos = i; } if (searchOK (-1, i, eh)) i--; // Look further to the left. else i = -1; // Cannot go any further to the left. } // Search for the best ladder on the right. j = ew; jlen = 0; jpos = -1; while (j < FIELDWIDTH) { if (searchOK (+1, j, eh)) { j++; // Look further to the right. rungs = distanceUp (j, eh, deltah); if (rungs > jlen) { jlen = rungs; // This the best yet. jpos = j; } } else j = FIELDWIDTH+1; // Cannot go any further to the right. } if ((ilen == 0) && (jlen == 0)) // No ladder found. return STAND; // Choose a ladder to go to. if (ilen != jlen) { // If the ladders are not the same // length, choose the longer one. if (ilen > jlen) { if (ipos == ew) // If already on the best ladder, go up. return UP; else return LEFT; } else return RIGHT; } else { // Both ladders are the same length. if (ipos == ew) // If already on the best ladder, go up. return UP; else if (ilen == deltah) { // If both reach the hero's level, if ((ew - ipos) <= (jpos - ew)) // choose the closest. return LEFT; else return RIGHT; } else return LEFT; // Else choose the left ladder. } }