/** * \fn MovementList* pathReConstruction(Node* finalNode) * \brief Searches through the list, the path. * * \param finalNode The destination node. * \return The direction an enemy must go. */ MovementList* pathReConstruction(Map *map, Node* finalNode) { Node* nextNode = finalNode; MovementList* list = newMovementList(STAY); while(finalNode->previousNode) { nextNode = finalNode; finalNode = finalNode->previousNode; Case* currentCase = getCase(map, finalNode->x, finalNode->y); Case* nearCase = getCase(map, nextNode->x, nextNode->y); list = headMovement(nextMove(*currentCase, *nearCase), list); } return list; }
void GameArena::createGraphics() { for(int i = 0; i < width; i++) { for(int j = 0; j < height; j++) { QGraphicsSquareItem *m_case = getCase(i,j); scene->addItem(m_case->getItem()); } } /* if(!graphicView) { graphicView = new QGraphicsView(mainWindow); int size = squareSize * (width+1); mainWindow->setMinimumSize(size,size); graphicView->setMinimumSize(size,size); graphicView->setScene(scene); graphicView->show(); graphicView->setFocus(); } else { graphicView->setScene(scene); } */ }
void Map::produceFood(Snake const *snake) { int ntry = 0; bool state; int x; int y; srand(time(0)); state = false; while (state == false && ntry < 1000) { x = rand() % (this->_height - 1) + 1; y = rand() % (this->_width - 1) + 1; state = true; if (getCase(x, y) != tEmpty) state = false; if (snake) { for (std::list<SnakeElement *>::const_iterator it = snake->getList().begin(); it != snake->getList().end(); ++it) { if (x == (*it)->getPos()[0] && y == (*it)->getPos()[1]) state = false; } } ntry++; } if (ntry == 1000) throw MapException("Impossible to produce food."); setCase(x, y, tFood); }
void GameArena::setMap(MapClient *newMap) { clear(); map = newMap; width = map->getWidth(); height = map->getHeight(); maxNbPlayers = map->getMaxNbPlayers(); squaresItem = new QGraphicsSquareItem*[width * height]; for(int i = 0; i < width; i++) { for(int j = 0; j < height; j++) { initCase(i,j); getCase(i,j)->setItem(pixmaps.getPixmap(map->getType(i,j))); if(map->getOption(i,j) != BlockMapProperty::none) { //add this option on the map. It won't be removed or changed during the game. QGraphicsSquareItem* optItem = new QGraphicsSquareItem(i * squareSize,j * squareSize,squareSize); optItem->setItem(pixmaps.getPixmap(map->getOption(i,j), map->getOptionDirection(i,j))); scene->addItem(optItem); optionsItems << optItem; } } } qint16 x,y; for(int i = 0; i < map->getNbPlayers(); i++) { map->getPlayerPosition(i,x,y); QPlayer *p = new QPlayer(i); playersItem.append(p); p->setPos(x-squareSize/2,y-squareSize/2,squareSize); scene->addItem(p); emit sigNewPlayerGraphic(i,*p->getPlayerPixmap()); } connect(map, SIGNAL(sigBlockChanged(int)), this, SLOT(blockChanged(int))); connect(map, SIGNAL(sigBlockChanged(int,int)), this, SLOT(blockChanged(int,int))); connect(map, SIGNAL(sigHeartbeatUpdated(qint32)), this, SLOT(slotHearbeatUpdated(qint32))); connect(map, SIGNAL(sigMovePlayer(int, int, int, int)), this, SLOT(movePlayer(int, int, int, int))); connect(map, SIGNAL(sigPlayerSickChanged(int, bool)), this, SLOT(slotPlayerSickChanged(int, bool))); connect(map, SIGNAL(sigKillPlayer(int)), this, SLOT(killPlayer(int))); connect(map, SIGNAL(sigAddBonus(Bonus::Bonus_t,qint16,qint16)), this, SLOT(slotAddBonus(Bonus::Bonus_t,qint16,qint16))); connect(map, SIGNAL(sigRemoveBonus(qint16,qint16)), this, SLOT(slotRemoveBonus(qint16,qint16))); connect(map, SIGNAL(sigAddBomb(int)), this, SLOT(slotAddBomb(int)), Qt::DirectConnection); connect(map, SIGNAL(sigMovedBomb(int)), this, SLOT(slotMovedBomb(int)), Qt::DirectConnection); connect(map, SIGNAL(sigFlyingBomb(int,qint32)), this, SLOT(slotFlyingBomb(int,qint32)), Qt::DirectConnection); connect(map, SIGNAL(sigRemoveBomb(int)), this, SLOT(slotRemoveBomb(int)), Qt::DirectConnection); connect(map, SIGNAL(sigRemoveBombRC(int)), this, SLOT(slotRemoveBombRC(int)), Qt::DirectConnection); connect(map, SIGNAL(sigAddFlame(int,qint16,qint16)), this, SLOT(slotAddFlame(int,qint16,qint16))); connect(map, SIGNAL(sigRemoveFlame(int)), this, SLOT(slotRemoveFlame(int))); createGraphics(); }
std::string Carte::afficherCase(int X, int Y) const { switch(getCase(X, Y)) { case LIBRE: return "Libre"; break; case CHEMIN_NORD: return "Nord"; break; case CHEMIN_SUD: return "Sud"; break; case CHEMIN_OUEST: return "Ouest"; break; case CHEMIN_EST: return "Est"; break; case CHEMIN_NO: return "Nord-Ouest"; break; case CHEMIN_NE: return "Nord-Est"; break; case CHEMIN_SO: return "Sud-Ouest"; break; case CHEMIN_SE: return "Sud-Est"; break; case DEPART_NORD: return "Depart nord"; break; case DEPART_SUD: return "Depart sud"; break; case DEPART_OUEST: return "Depart ouest"; break; case DEPART_EST: return "Depart est"; break; case BUT_ENNEMIS: return "But"; break; case BOUE: return "Sud-Est"; break; default: return "Erreur de case"; break; } }
/** * Représente une grille. * @param grid Grille à remplir * @param argc Nombres d'arguments du main * @param gridStr Grille sous forme de chaîne */ void Grille(t_Case grid[N][N],int argc, char * gridStr[]){ int i, j; int nb_bonus[2] = {0}; initRand(); initGrid(grid); // Affichage grille aléatoire ou définis par l'utilisateur printf("----------------------------------------------------\n"); printf("|"); if(argc == 1){ for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { getCase(grid, i, j, nb_bonus); } printf("\n----------------------------------------------------\n"); if(i < N-1 )printf("|"); } }else if(argc == 2){ if(strlen(gridStr[1]) >= 16){ gridStr[16] = '\0'; for (i = 0; i < 16; i++) { // Vérifie que le caractère courant est valide if(!isalpha(gridStr[1][i])){ printf("\nErreur caractère invalide !\n"); exit(0); } getCaseFromStr(grid, nb_bonus, gridStr[1], i); if((i - 3) % 4 == 0){ printf("\n----------------------------------------------------\n"); if(i < 12)printf("|"); } } }else{ printf("Chaîne de caractère trop courte."); } }else{ printf("Erreur nombre d'arguments incorrect !\nNormal usage: ./bin/ruzzleSolver [a-z]*16\n"); exit(0); } }
float Carte::getAngle(int X, int Y) const { ENTITES tmp = getCase(X, Y); switch(tmp) { case LIBRE: case DEPART_NORD: case BUT_ENNEMIS: case BOUE: return 90; break; case CHEMIN_NORD: return 270; break; case CHEMIN_SUD: return 90; break; case CHEMIN_EST: return 0; break; case CHEMIN_OUEST: return 180; break; case CHEMIN_NE: return 315; break; case CHEMIN_SE: return 45; break; case CHEMIN_NO: return 225; break; case CHEMIN_SO: return 135; break; default: return 90; break; } }
/** * \fn MovementList* searchPath(Case start, Case destination) * \brief The A star algorithm implementation. * * \param start The case where a enemy is. * \param destination The case a enemy must go. * \return The path. */ MovementList* searchPath(Map *map, Case start, Case destination) { //Initialisation Node* endNode = getNode(destination); Node* firstNode = getNode(start); firstNode->cumulateNodeCost = 0; MovementList* nextMoves; /* There are two lists : - the openList contains a set of to process node; - the closedList contains a set of already processed node */ List* openList = newList(NULL); openList = head(firstNode, openList); List* closedList = NULL; // *A Star* /* if there aren't any node in openList and the path aren't be found, there aren't any path */ while(openList->nextList) { Node* lowestHeuristic = popHead(&openList); // we test the most closer node (with the lowest heuristic cost) if(theseTwoNodeAreEquals(lowestHeuristic,endNode)) { nextMoves = pathReConstruction(map, lowestHeuristic); // if we have reached the final node, a path have been found freeList(openList); freeList(closedList); return nextMoves; } closedList = push(lowestHeuristic,closedList); // this node have been computed /* For each node near the one which is computed, we check if he have already computed or cannot be tested (if it's a wall or a tower) */ int i, j; float k; for( i=-1, j=0, k=0.5; k<=2; j =- ((( (int)(-2*k) - 1 )%3)+1), i=(int)(k+=0.5) - 1 ) { // i={-1,0,0,1} j={0,1,-1,0} Case nearCase = *getCase(map, i+lowestHeuristic->x, j+lowestHeuristic->y); // get the four Case near the one already computed Node *nearNode = getNode(nearCase); if(nearCase.hasTower || amIInDaList(nearNode, closedList)) { // we are not open to node already computed or continue; // wich can't be walked on } /* * then we calculate their heuristic cost (node with less heuristic are prefered * for the path) */ // complete node's construction nearNode->previousNode = lowestHeuristic; // and calculate it heuristic nearNode->cumulateNodeCost = heuristicCost(nearNode,endNode); Node *openNode = amIInDaList(nearNode,openList); //if the node is already in the openList if(openNode){ //we check if the new one have better heuristic if(openNode->cumulateNodeCost > nearNode->cumulateNodeCost) { //if so, we switch the two node openNode->cumulateNodeCost = nearNode->cumulateNodeCost; //else (if it is not in the openList) openNode->previousNode = nearNode->previousNode; //we simply put it in } } else { openList = push(nearNode,openList); } } } freeList(openList); freeList(closedList); return NULL; }
void GameArena::blockChanged(int pos) { QGraphicsSquareItem* tempItem = getCase(pos); //qDebug() << "Wall: " << tempItem->getItem()->pixmap().cacheKey() << ", new value: " << pixmaps.getPixmap(map->getType(pos)).cacheKey(); tempItem->setItem(pixmaps.getPixmap(map->getType(pos))); }
int main(int argc, char* argv[]) { // Init initPath(argv[0]); SDL_Surface* screen = NULL; SDL_Event event; int *seed; srand((int)seed); int previousTime = 0, currentTime = 0; Events *flags = createEventFlags(); SDL_Init(SDL_INIT_VIDEO); SDL_SetEventFilter(eventFilter); screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_DOUBLEBUF | SDL_NOFRAME); SDL_WM_SetCaption("Tower Defense", NULL); Action *actionList = initAction(); Map* map = createMap(getPath("resources/Forest.png")); _map = map; SDL_Rect surface = {0, 0, 720, 600}; Viewport* viewport = createViewport(screen, surface, map); _viewport = viewport; // FIXME uh? what's this thing? surface.x = 800 - 80; surface.y = 0; surface.h = 80; surface.w = 600; // Creation of the enemies TypeEn *whiteCat = createTypeEn(100, 5, false, true, true, false, 1,getPath("resources/white_transparent_cat.png")); TypeEn *blackCat = createTypeEn(100, 5, false, true, true, false, 1,getPath("resources/black_transparent_cat.png")); Enemy *cat1 = createEnemy(1,1,whiteCat); Enemy *cat2 = createEnemy(1,10,whiteCat); Enemy *cat3 = createEnemy(5,5,blackCat); Enemy *cat4 = createEnemy(21,4,blackCat); TypeEn *zombie = createTypeEn(100,5,false,true,true,false,1,getPath("resources/zombie.png")); Enemy *zombie1 = createEnemy(4,4,zombie); Enemy *zombie2 = createEnemy(9,4,zombie); Enemy *zombie3 = createEnemy(9,9,zombie); Enemy *zombie4 = createEnemy(7,14,zombie); //Add enemy in the List List *catList = newList(cat4); pushList((void*)catList,cat2); pushList((void*)catList,cat3); // pushList((void*)catList,cat1); List *zombieList = newList(zombie1); /* pushList((void*)zombieList,zombie2);*/ /* pushList((void*)zombieList,zombie3);*/ /* pushList((void*)zombieList,zombie4);*/ // removeEnemyFromList(cat4,catList); //TOWER TypeBul *bullet = createTypeBul(getPath("resources/bullet.png"), 1); TypeTo *tower = createTypeTo(0,5,0,0,false,false,false,false,bullet,NULL,getPath("resources/tower.png")); upgradeTypeTo(tower,0.5,getPath("resources/towerUP.png")); flags->selectedTower = tower->nextType; Tower *tower1 = createTower(7,7,tower); List *towerList = newList(tower1); flags->towerList = towerList; // Create and Renders the right panel game menu SDL_Rect surfaceMenu = {720, 0, 800, 600}; Menu* menu = menu_create(screen, surfaceMenu); menu_loadBackground(menu, "resources/enemyFont.gif"); // For testing only, we add a few random buttons menu_addButton(menu, button_createBuildButton(tower)); menu_addButton(menu, button_createBuildButton(tower)); menu_addButton(menu, button_createBuildButton(tower)); menu_render(menu); _cell = *getCase(20,11); // Main loop while(actionList[QUIT].boolean == NULL) { // Managing the events manageEvents(viewport, flags,actionList); for(int i=1; i<ACTION_LENGTH; i++) { if(actionList[i].boolean) { int repeat = (*actionList[i].action)(viewport,flags,actionList[i].boolean); if(!repeat) { actionList[i].boolean = NULL; } } } // Redraws the map (viewport contents) before blitting stuff on it updateViewport(viewport); ///////////////////////////// DEBUG WALL ///////////////////////////// SDL_Rect position; for(int i=0; i < _map->nbCaseW; i++) { for(int j=0; j < _map->nbCaseH; j++) { Case cell = *getCase(i,j); position.x = cell.x; position.y = cell.y; if(map->matrice[i][j].hasTower == 2) { SDL_Surface *wall = IMG_Load(getPath("resources/brick.png")); blitToViewport(viewport, wall, NULL, &position); } } } position.x = _cell.x; position.y = _cell.y; blitToViewport(viewport, IMG_Load(getPath("resources/candy_cane.png")), NULL, &position); ///////////////////////////////////////////////////////////////////// // Move enemies if(flags->enemy_Path_Calculation) { pathReCalculation(catList); pathReCalculation(zombieList); flags->enemy_Path_Calculation = false; } moveEnemyList(zombieList); moveEnemyList(catList); // Blit enemies drawEnemyList(zombieList); drawEnemyList(catList); //Blit TOWER /* if(event.key.keysym.sym == SDLK_u){*/ /* upgrade(tower1);*/ /* }*/ Bullet *bullet1 = createBullet(tower1); animateBullet(bullet1); drawTowerList(towerList); /* This should be handled by event.c switch(event.key.keysym.sym){ case SDLK_a: flags->selectedTower = tower; break; case SDLK_b: flags->selectedTower = tower->nextType; break; default: break; }*/ /* */ // Ask SDL to swap framebuffers to update the displayed screen SDL_Flip(screen); // Managing frames currentTime = SDL_GetTicks(); if (currentTime - previousTime <= 20) { SDL_Delay(20 - (currentTime - previousTime)); } // DEBUG printf("Frame %i : %ims\n", framecounter++, currentTime - previousTime); previousTime = SDL_GetTicks(); } free(actionList); SDL_Quit(); return EXIT_SUCCESS; }
std::string BaseLoop::decodeMessage(const std::string& data) { std::ostringstream result; std::string cycdata; int index; // prepare data std::string token; std::istringstream stream(data); std::vector<std::string> cmd; while (std::getline(stream, token, ' ') != 0) cmd.push_back(token); if (cmd.size() == 0) return "command missing"; switch (getCase(cmd[0])) { case notfound: result << "command not found"; break; case get: if (cmd.size() < 3 || cmd.size() > 4) { result << "usage: 'get class cmd (sub)'"; break; } index = m_commands->findCommand(data); if (index >= 0) { std::string type = m_commands->getType(index); std::string ebusCommand(A.getParam<const char*>("p_address")); ebusCommand += m_commands->getEbusCommand(index); std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); L.log(bas, trace, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); // send busCommand m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); BusCommand* busCommand = m_ebusloop->getBusCommand(); if (busCommand->getResult().c_str()[0] != '-') { // decode data Command* command = new Command(index, (*m_commands)[index], busCommand->getResult()); // return result result << command->calcResult(cmd); delete command; } else { L.log(bas, error, " %s", busCommand->getResult().c_str()); result << busCommand->getResult(); } delete busCommand; } else { result << "ebus command not found"; } break; case set: if (cmd.size() != 4) { result << "usage: 'set class cmd value'"; break; } index = m_commands->findCommand(data.substr(0, data.find(cmd[3])-1)); if (index >= 0) { std::string type = m_commands->getType(index); std::string ebusCommand(A.getParam<const char*>("p_address")); ebusCommand += m_commands->getEbusCommand(index); // encode data Command* command = new Command(index, (*m_commands)[index], cmd[3]); std::string value = command->calcData(); if (value[0] != '-') { ebusCommand += value; } else { L.log(bas, error, " %s", value.c_str()); delete command; break; } std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); L.log(bas, event, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); // send busCommand m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); BusCommand* busCommand = m_ebusloop->getBusCommand(); if (busCommand->getResult().c_str()[0] != '-') { // decode result if (busCommand->getResult().substr(busCommand->getResult().length()-8) == "00000000") result << "done"; else result << "error"; } else { L.log(bas, error, " %s", busCommand->getResult().c_str()); result << busCommand->getResult(); } delete busCommand; delete command; } else { result << "ebus command not found"; } break; case cyc: if (cmd.size() < 3 || cmd.size() > 4) { result << "usage: 'cyc class cmd (sub)'"; break; } index = m_commands->findCommand(data); if (index >= 0) { // get cycdata cycdata = m_cycdata->getData(index); if (cycdata != "") { // decode data Command* command = new Command(index, (*m_commands)[index], cycdata); // return result result << command->calcResult(cmd); delete command; } else { result << "no data stored"; } } else { result << "ebus command not found"; } break; case hex: if (cmd.size() != 3) { result << "usage: 'hex type value' (value: ZZPBSBNNDx)"; break; } if ((strcasecmp(cmd[1].c_str(), "MS") == 0) || (strcasecmp(cmd[1].c_str(), "MM") == 0) || (strcasecmp(cmd[1].c_str(), "BC") == 0)) { std::string type = cmd[1]; std::string ebusCommand(A.getParam<const char*>("p_address")); cmd[2].erase(std::remove_if(cmd[2].begin(), cmd[2].end(), isspace), cmd[2].end()); ebusCommand += cmd[2]; std::transform(ebusCommand.begin(), ebusCommand.end(), ebusCommand.begin(), tolower); L.log(bas, trace, " type: %s msg: %s", type.c_str(), ebusCommand.c_str()); // send busCommand m_ebusloop->addBusCommand(new BusCommand(type, ebusCommand)); BusCommand* busCommand = m_ebusloop->getBusCommand(); if (busCommand->getResult().c_str()[0] == '-') L.log(bas, error, " %s", busCommand->getResult().c_str()); result << busCommand->getResult(); delete busCommand; } else { result << "specified message type is incorrect"; } break; case dump: if (cmd.size() != 2) { result << "usage: 'dump state' (state: on|off)"; break; } if (cmd[1] == "on") m_ebusloop->dump(true); if (cmd[1] == "off") m_ebusloop->dump(false); result << "done"; break; case logarea: if (cmd.size() != 2) { result << "usage: 'logarea area,area,..' (area: bas|net|bus|cyc|all)"; break; } L.getSink(0)->setAreas(calcArea(cmd[1])); result << "done"; break; case loglevel: if (cmd.size() != 2) { result << "usage: 'loglevel level' (level: error|event|trace|debug)"; break; } L.getSink(0)->setLevel(calcLevel(cmd[1])); result << "done"; break; case help: result << "commands:" << std::endl << " get - fetch ebus data 'get class cmd (sub)'" << std::endl << " set - set ebus values 'set class cmd value'" << std::endl << " cyc - fetch cycle data 'cyc class cmd (sub)'" << std::endl << " hex - send given hex value 'hex type value' (value: ZZPBSBNNDx)" << std::endl << " dump - change dump state 'dump state' (state: on|off)" << std::endl << " logarea - change log area 'logarea area,area,..' (area: bas|net|bus|cyc|all)" << std::endl << " loglevel - change log level 'loglevel level' (level: error|event|trace|debug)" << std::endl << " quit - close connection" << std::endl << " help - print this page"; break; default: break; } return result.str(); }
/** * \fn Case* whiteCase(int x, int y) * \brief Gets a Case from a pixel position. * * \param Map Map on which to get the case from * \param x X coordinate. * \param y Y coordinate. * \return A cell's pointer. */ Case* whichCase(Map* map, int x, int y) { x /= CSIZE; y /= CSIZE; return getCase(map, x,y); }