/** This function sets a default successor for all graph nodes that currently * don't have a successor defined. The default successor of node X is X+1. */ void QuadGraph::setDefaultSuccessors() { for(unsigned int i=0; i<m_all_nodes.size(); i++) { if(m_all_nodes[i]->getNumberOfSuccessors()==0) { addSuccessor(i,i+1>=m_all_nodes.size() ? 0 : i+1); //~ m_all_nodes[i]->addSuccessor(i+1>=m_all_nodes.size() ? 0 : i+1); } // if size==0 } // for i<m_allNodes.size() } // setDefaultSuccessors
bool MapSearchNode::GetSuccessors(AStarSearch<MapSearchNode>* astarsearch, MapSearchNode* parent_node) { int16_t parent_x = -1; int16_t parent_y = -1; if (parent_node != nullptr) { parent_x = parent_node->x; parent_y = parent_node->y; } bool canWalkLeft = addSuccessor(astarsearch, x - 1, y, parent_x, parent_y); bool canWalkRight = addSuccessor(astarsearch, x + 1, y, parent_x, parent_y); bool canWalkUp = addSuccessor(astarsearch, x, y - 1, parent_x, parent_y); bool canWalkDown = addSuccessor(astarsearch, x, y + 1, parent_x, parent_y); if (canWalkLeft == true) { if (canWalkUp == true) { addSuccessor(astarsearch, x - 1, y - 1, parent_x, parent_y); } if (canWalkDown == true) { addSuccessor(astarsearch, x - 1, y + 1, parent_x, parent_y); } } if (canWalkRight == true) { if (canWalkUp == true) { addSuccessor(astarsearch, x + 1, y - 1, parent_x, parent_y); } if (canWalkDown == true) { addSuccessor(astarsearch, x + 1, y + 1, parent_x, parent_y); } } return true; }
void BasicBlock::disasm() { if (isDisasmed()) return; setDisasmed(true); DISASM MyDisasm = insts[0]; insts.pop_back(); //printf("\t\tStart BasicBlock::disasm 0x%llx\n", (ADDR)this); while (1){ // Fix SecurityBlock MyDisasm.SecurityBlock = func->getEnd() - MyDisasm.EIP; // disasm int len = Disasm(&MyDisasm); if (len == OUT_OF_BLOCK) { puts("\t\t\tOUT_OF_BLOCK : Disasm finished"); return; }else if (len == UNKNOWN_OPCODE) { fprintf(stderr, "unknown opcode\n"); return; }else { if((MyDisasm.Instruction.Category&0xffff)==CONTROL_TRANSFER && MyDisasm.Instruction.BranchType) { switch (MyDisasm.Instruction.BranchType) { case CallType: break; case JO: case JC: case JE: case JA: case JS: case JP: case JL: case JG: //case JB: case JECXZ: case JNO: case JNC: case JNE: case JNA: case JNS: case JNP: case JNL: case JNG: //case JNB: { ADDR mAddr = MyDisasm.EIP + len; if ((ADDR)-1 != func->getVirAddr(mAddr)) { BasicBlock *succ = func->findBasicBlock(mAddr); addSuccessor(succ); succ->addPredecessor(this); } } case JmpType: if (MyDisasm.Instruction.AddrValue != 0) { ADDR mAddr = func->getMapAddr(MyDisasm.Instruction.AddrValue); if ((ADDR)-1 != mAddr) { BasicBlock *succ = func->findBasicBlock(mAddr); addSuccessor(succ); succ->addPredecessor(this); } } case RetType: //puts("\t\t\tCONTROL_TRANSFER : Disasm finished"); //char buf[1024]; //printf("\t\t%s\n\n", toString(buf, sizeof(buf))); insts.push_back(MyDisasm); return; default: fprintf(stderr, "unknown branchtype %d (0x%llx) in Basic Block 0x%llx\n", MyDisasm.Instruction.BranchType, (ADDR)MyDisasm.VirtualAddr, getFirstInstAddr()); return; } } insts.push_back(MyDisasm); MyDisasm.EIP = MyDisasm.EIP + len; MyDisasm.VirtualAddr = MyDisasm.VirtualAddr + len; if(MyDisasm.EIP >= func->getEnd()){ //puts("\t\t\tFUNCTION END : Disasm finished"); char buf[1024]; //printf("\t\t%s\n\n", toString(buf, sizeof(buf))); return; } } } }
/** Loads a quad graph from a file. * \param filename Name of the file to load. */ void QuadGraph::load(const std::string &filename) { const XMLNode *xml = file_manager->createXMLTree(filename); if(!xml) { // No graph file exist, assume a default loop X -> X+1 // i.e. each quad is part of the graph exactly once. // First create an empty graph node for each quad: for(unsigned int i=0; i<QuadSet::get()->getNumberOfQuads(); i++) m_all_nodes.push_back(new GraphNode(i, (unsigned int) m_all_nodes.size())); // Then set the default loop: setDefaultSuccessors(); computeDirectionData(); if (m_all_nodes.size() > 0) { m_lap_length = m_all_nodes[m_all_nodes.size()-1]->getDistanceFromStart() + m_all_nodes[m_all_nodes.size()-1]->getDistanceToSuccessor(0); } else { Log::error("Quad Graph", "No node in driveline graph."); m_lap_length = 10.0f; } return; } // The graph file exist, so read it in. The graph file must first contain // the node definitions, before the edges can be set. for(unsigned int node_index=0; node_index<xml->getNumNodes(); node_index++) { const XMLNode *xml_node = xml->getNode(node_index); // First graph node definitions: // ----------------------------- if(xml_node->getName()=="node-list") { // A list of quads is connected to a list of graph nodes: unsigned int from, to; xml_node->get("from-quad", &from); xml_node->get("to-quad", &to); for(unsigned int i=from; i<=to; i++) { m_all_nodes.push_back(new GraphNode(i, (unsigned int) m_all_nodes.size())); } } else if(xml_node->getName()=="node") { // A single quad is connected to a single graph node. unsigned int id; xml_node->get("quad", &id); m_all_nodes.push_back(new GraphNode(id, (unsigned int) m_all_nodes.size())); } // Then the definition of edges between the graph nodes: // ----------------------------------------------------- else if(xml_node->getName()=="edge-loop") { // A closed loop: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); for(unsigned int i=from; i<=to; i++) { assert(i!=to ? i+1 : from <m_all_nodes.size()); addSuccessor(i,(i!=to ? i+1 : from)); //~ m_all_nodes[i]->addSuccessor(i!=to ? i+1 : from); } } else if(xml_node->getName()=="edge-line") { // A line: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); for(unsigned int i=from; i<to; i++) { addSuccessor(i,i+1); //~ m_all_nodes[i]->addSuccessor(i+1); } } else if(xml_node->getName()=="edge") { // Adds a single edge to the graph: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); assert(to<m_all_nodes.size()); addSuccessor(from,to); //~ m_all_nodes[from]->addSuccessor(to); } // edge else { Log::error("Quad Graph", "Incorrect specification in '%s': '%s' ignored.", filename.c_str(), xml_node->getName().c_str()); continue; } // incorrect specification } delete xml; setDefaultSuccessors(); computeDistanceFromStart(getStartNode(), 0.0f); computeDirectionData(); // Define the track length as the maximum at the end of a quad // (i.e. distance_from_start + length till successor 0). m_lap_length = -1; for(unsigned int i=0; i<m_all_nodes.size(); i++) { float l = m_all_nodes[i]->getDistanceFromStart() + m_all_nodes[i]->getDistanceToSuccessor(0); if(l > m_lap_length) m_lap_length = l; } } // load
/** Loads a drive graph from a file. * \param filename Name of the quad file to load. * \param filename Name of the graph file to load. */ void DriveGraph::load(const std::string &quad_file_name, const std::string &filename) { XMLNode *quad = file_manager->createXMLTree(quad_file_name); if (!quad || quad->getName() != "quads") { Log::error("DriveGraph : Quad xml '%s' not found.", filename.c_str()); delete quad; return; } // Each quad is part of the graph exactly once now. for (unsigned int i = 0; i < quad->getNumNodes(); i++) { const XMLNode *xml_node = quad->getNode(i); if (xml_node->getName() != "quad") { Log::warn("DriveGraph: Unsupported node type '%s' found in '%s' - ignored.", xml_node->getName().c_str(), filename.c_str()); continue; } // Note that it's not easy to do the reading of the parameters here // in quad, since the specification in the xml can contain references // to previous points. E.g.: // <quad p0="40:3" p1="40:2" p2="25.396030 0.770338 64.796539" ... Vec3 p0, p1, p2, p3; getPoint(xml_node, "p0", &p0); getPoint(xml_node, "p1", &p1); getPoint(xml_node, "p2", &p2); getPoint(xml_node, "p3", &p3); bool invisible = false; xml_node->get("invisible", &invisible); bool ai_ignore = false; xml_node->get("ai-ignore", &ai_ignore); bool ignored = false; std::string direction; xml_node->get("direction", &direction); if (direction == "forward" && race_manager->getReverseTrack()) { ignored = true; invisible = true; ai_ignore = true; } else if (direction == "reverse" && !race_manager->getReverseTrack()) { ignored = true; invisible = true; ai_ignore = true; } createQuad(p0, p1, p2, p3, m_all_nodes.size(), invisible, ai_ignore, false/*is_arena*/, ignored); } delete quad; const XMLNode *xml = file_manager->createXMLTree(filename); if(!xml) { // No graph file exist, assume a default loop X -> X+1 // Set the default loop: setDefaultSuccessors(); computeDirectionData(); if (m_all_nodes.size() > 0) { m_lap_length = getNode(m_all_nodes.size()-1)->getDistanceFromStart() + getNode(m_all_nodes.size()-1)->getDistanceToSuccessor(0); } else { Log::error("DriveGraph", "No node in driveline graph."); m_lap_length = 10.0f; } return; } // The graph file exist, so read it in. The graph file must first contain // the node definitions, before the edges can be set. for(unsigned int node_index=0; node_index<xml->getNumNodes(); node_index++) { const XMLNode *xml_node = xml->getNode(node_index); // Load the definition of edges between the graph nodes: // ----------------------------------------------------- if (xml_node->getName() == "node-list") { // Each quad is part of the graph exactly once now. unsigned int to = 0; xml_node->get("to-quad", &to); assert(to + 1 == m_all_nodes.size()); continue; } else if(xml_node->getName()=="edge-loop") { // A closed loop: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); for(unsigned int i=from; i<=to; i++) { assert(i!=to ? i+1 : from <m_all_nodes.size()); addSuccessor(i,(i!=to ? i+1 : from)); //~ m_all_nodes[i]->addSuccessor(i!=to ? i+1 : from); } } else if(xml_node->getName()=="edge-line") { // A line: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); for(unsigned int i=from; i<to; i++) { addSuccessor(i,i+1); //~ m_all_nodes[i]->addSuccessor(i+1); } } else if(xml_node->getName()=="edge") { // Adds a single edge to the graph: unsigned int from, to; xml_node->get("from", &from); xml_node->get("to", &to); assert(to<m_all_nodes.size()); addSuccessor(from,to); //~ m_all_nodes[from]->addSuccessor(to); } // edge else { Log::error("DriveGraph", "Incorrect specification in '%s': '%s' ignored.", filename.c_str(), xml_node->getName().c_str()); continue; } // incorrect specification } delete xml; setDefaultSuccessors(); computeDistanceFromStart(getStartNode(), 0.0f); computeDirectionData(); // Define the track length as the maximum at the end of a quad // (i.e. distance_from_start + length till successor 0). m_lap_length = -1; for(unsigned int i=0; i<m_all_nodes.size(); i++) { float l = getNode(i)->getDistanceFromStart() + getNode(i)->getDistanceToSuccessor(0); if(l > m_lap_length) m_lap_length = l; } loadBoundingBoxNodes(); } // load
std::list<mlcore::Successor> GridWorldProblem::transition(mlcore::State *s, mlcore::Action *a) { GridWorldState* state = static_cast<GridWorldState *> (s); GridWorldAction* action = static_cast<GridWorldAction *> (a); std::list<mlcore::Successor> successors; if (s == absorbing || gridGoal(state)) { successors.push_front(mlcore::Successor(absorbing, 1.0)); return successors; } double probForward = 0.8; int numSuccessors = allDirections_ ? 3 : 2; double probSides = 0.2 / numSuccessors; if (action->dir() == gridworld::UP) { addSuccessor(state, successors, height_ - 1, state->y(), state->x(), state->y() + 1, probForward); addSuccessor(state, successors, state->x(), 0, state->x() - 1, state->y(), probSides); addSuccessor(state, successors, width_ - 1, state->x(), state->x() + 1, state->y(), probSides); if (allDirections_) { addSuccessor(state, successors, state->y(), 0, state->x(), state->y() - 1, probSides); } } else if (action->dir() == gridworld::DOWN) { addSuccessor(state, successors, state->y(), 0, state->x(), state->y() - 1, probForward); addSuccessor(state, successors, state->x(), 0, state->x() - 1, state->y(), probSides); addSuccessor(state, successors, width_ - 1, state->x(), state->x() + 1, state->y(), probSides); if (allDirections_) { addSuccessor(state, successors, height_ - 1, state->y(), state->x(), state->y() + 1, probSides); } } else if (action->dir() == gridworld::LEFT) { addSuccessor(state, successors, state->x(), 0, state->x() - 1, state->y(), probForward); addSuccessor(state, successors, state->y(), 0, state->x(), state->y() - 1, probSides); addSuccessor(state, successors, height_ - 1, state->y(), state->x(), state->y() + 1, probSides); if (allDirections_) { addSuccessor(state, successors, width_ - 1, state->x(), state->x() + 1, state->y(), probSides); } } else if (action->dir() == gridworld::RIGHT) { addSuccessor(state, successors, width_ - 1, state->x(), state->x() + 1, state->y(), probForward); addSuccessor(state, successors, state->y(), 0, state->x(), state->y() - 1, probSides); addSuccessor(state, successors, height_ - 1, state->y(), state->x(), state->y() + 1, probSides); if (allDirections_) { addSuccessor(state, successors, state->x(), 0, state->x() - 1, state->y(), probSides); } } return successors; }
/*-----------------------------------------------------------------*/ static void eBBSuccessors (ebbIndex * ebbi) { eBBlock ** ebbs = ebbi->bbOrder; int count = ebbi->count; int i = 0; /* for all the blocks do */ for (; i < count; i++) { iCode *ic; if (ebbs[i]->noPath) continue; ebbs[i]->succVect = newBitVect (count); /* if the next on exists & this one does not */ /* end in a GOTO or RETURN then the next is */ /* a natural successor of this. Note we have */ /* consider eBBlocks with no instructions */ if (ebbs[i + 1]) { if (ebbs[i]->ech) { bool foundNoReturn = FALSE; if (ebbs[i]->ech->op == CALL || ebbs[i]->ech->op == PCALL) { sym_link *type = operandType (IC_LEFT (ebbs[i]->ech)); if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) foundNoReturn = TRUE; } if (!foundNoReturn && ebbs[i]->ech->op != GOTO && ebbs[i]->ech->op != RETURN && ebbs[i]->ech->op != JUMPTABLE) { int j = i + 1; while (ebbs[j] && ebbs[j]->noPath) j++; addSuccessor (ebbs[i], ebbs[j]); /* add it */ } else { if (i && ebbs[i-1]->ech && ebbs[i-1]->ech->op==IFX) { ebbs[i]->isConditionalExitFrom=ebbs[i-1]; } } } /* no instructions in the block */ /* could happen for dummy blocks */ else addSuccessor (ebbs[i], ebbs[i + 1]); } /* go thru all the instructions: if we find a */ /* goto or ifx or a return then we have a succ */ if ((ic = ebbs[i]->ech)) { eBBlock *succ; /* special case for jumptable */ if (ic->op == JUMPTABLE) { symbol *lbl; for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl; lbl = setNextItem (IC_JTLABELS (ic))) addSuccessor (ebbs[i], eBBWithEntryLabel (ebbi, lbl)); } else { succ = NULL; /* depending on the instruction operator */ switch (ic->op) { case GOTO: /* goto has edge to label */ succ = eBBWithEntryLabel (ebbi, ic->label); break; case IFX: /* conditional jump */ /* if true label is present */ if (IC_TRUE (ic)) succ = eBBWithEntryLabel (ebbi, IC_TRUE (ic)); else succ = eBBWithEntryLabel (ebbi, IC_FALSE (ic)); break; case RETURN: /* block with return */ succ = eBBWithEntryLabel (ebbi, returnLabel); break; } /* if there is a successor add to the list */ /* if it is not already present in the list */ if (succ) addSuccessor (ebbs[i], succ); } } } }