Esempio n. 1
0
QList<unsigned char> cPathfinding::find(P_CHAR pChar, const Coord &from, const Coord &to)
{
	QList<unsigned char> result;
	int i;

	// We can only calculate a path on the normal maps and if the destination is not out of range
	if (from.isInternalMap() || from.distance(to) > (unsigned int)areaSize) {
		return result;
	}

	memset(touched, 0, sizeof(bool) * nodeCount); // Clear the touched nodes
	this->goal = to; // Save the goal

	// Actually th�s should be the x/y offset of our area
	xoffset = (from.x + to.x - areaSize) / 2;
	yoffset = (from.y + to.y - areaSize) / 2;

	int fromNode = getNodeIndex(from.x, from.y, from.z);
	int toNode = getNodeIndex(to.x, to.y, to.z);
	openlist = fromNode; // Where are we

	// Initialize the node
	nodes[fromNode].cost = 0;
	nodes[fromNode].total = heuristic(from.x - xoffset, from.y - yoffset, from.z);
	nodes[fromNode].parent = -1;
	nodes[fromNode].next = -1;
	nodes[fromNode].prev = -1;
	nodes[fromNode].z = from.z;

	// We touched this node
	onopen[fromNode] = true;
	touched[fromNode] = true;

	int depth = 0;
	int newTotal, newCost;

	// This is controlled by the npc moving. Some npcs can fly (move over impassables)
	// others can open doors
	ignoreDoors = false;
	ignoreMovableImpassables = false;
	int successors[8]; // List of successor nodes used in subsequent iterations. Never more than 8
	int successorCount; // Number of successors found

	while (openlist != -1) {
		if (++depth > maxDepth)
			break; // Break if we would exceed the maximum iteration count

		int bestnode = findBest(openlist);

		// Get adjacent nodes that we can walk to
		successorCount = getSuccessors(bestnode, pChar, successors);

		if (successorCount == 0) {
			break; // We've run into a situation where we'll never find a suitable successor
		}

		// Follow every possible successor
		for (i = 0; i < successorCount; ++i) {
			int successor = successors[i];

			if (touched[successor]) {
				continue; // If we worked on the node already, skip this part
			}

			// calculate the cost of the successor based on the currents node cost
			newCost = nodes[bestnode].cost + 1;
			newTotal = newCost + heuristic(successor % areaSize, (successor / areaSize) % areaSize, nodes[successor].z);

			// Always execute, !wasTouched was always true here
			// if ( !wasTouched || m_Nodes[newNode].total > newTotal )
			nodes[successor].parent = bestnode;
			nodes[successor].cost = newCost;
			nodes[successor].total = newTotal;
			addToChain(successor);

			// We found our target
			if (successor == toNode) {
				int pathCount = 0; // Stack allocation speed isn't a concern here anymore
				int parent = nodes[successor].parent;

				// Record the path in reverse order
				while (parent != -1) {
					path[pathCount++] = getDirection(parent % areaSize, (parent / areaSize) % areaSize, successor % areaSize, (successor / areaSize) % areaSize);
					successor = parent; // Track back
					parent = nodes[successor].parent;

					if (successor == fromNode) {
						break;
					}
				}

				int backtrack = 0;
				while (pathCount != 0) {
					result.append( path[--pathCount] );
				}
				return result; // Immediately return
			}
		}
	}

	return result; // Nothing found
}
Esempio n. 2
0
int checkPattern( int rule, char *arg )
{
  int ret=0;
  char term1[MEMORY_ELEMENT_SIZE+1];
  char term2[MEMORY_ELEMENT_SIZE+1];
  memoryElementType *antecedent = ruleSet[rule].antecedent;

  /* Build a replacement string (based upon the '?' element) */
  while (antecedent) {

    sscanf( antecedent->element, "(%s %s)", term1, term2);
    if (term2[strlen(term2)-1] == ')') term2[strlen(term2)-1] = 0;

    /* If the antecedent element is variable, find the matches
     * in the working memory and store the matched terms.
     */
    if (term2[0] == '?') {
      int i;
      char wm_term1[MEMORY_ELEMENT_SIZE+1];
      char wm_term2[MEMORY_ELEMENT_SIZE+1];

      for (i = 0 ; i < MAX_MEMORY_ELEMENTS ; i++) {

        if (workingMemory[i].active) {

          sscanf( workingMemory[i].element, "(%s %s)", wm_term1, wm_term2 );
          if (wm_term2[strlen(wm_term2)-1] == ')') 
            wm_term2[strlen(wm_term2)-1] = 0; 

          if (!strncmp(term1, wm_term1, strlen(term1))) addToChain(wm_term2);
      
        }

      }

    }

    antecedent = antecedent->next;

  }

  /* Now that we have the replacement strings, walk through the rules trying
   * the replacement string when necessary.
   */

  do {

    memoryElementType *curRulePtr, *temp;

    curRulePtr = ruleSet[rule].antecedent;

    while (curRulePtr) {

      sscanf( curRulePtr->element, "(%s %s)", term1, term2 );
      if (term2[strlen(term2)-1] == ')') term2[strlen(term2)-1] = 0;

      if (!strncmp( term1, "true", strlen(term1))) {
        ret = 1;
        break;
      } else {
        if ((term2[0] == '?') && (chain)) strcpy(term2, chain->element);
      }

      ret = searchWorkingMemory( term1, term2 );

      if (!ret) break;

      curRulePtr = curRulePtr->next;

    }

    if (ret) {

      /* Cleanup the replacement string chain */
      while (chain) {
        temp = chain;
        chain = chain->next;
        free(temp);
      }

      strcpy(arg, term2);

    } else {

      if (chain) {
        temp = chain;
        chain = chain->next;
        free(temp);
      }

    }

  } while (chain);

  return ret;
}