void
TestDecisionEquality
	(
	const JCharacter* fileName
	)
{
	std::ifstream input(fileName);

	TestVarList theVarList(input);

	JDecision* d1 = NULL;
	JDecision* d2 = NULL;
	while (1)
		{
		if (!GetDecision(input, &theVarList, &d1))
			{
			break;
			}
		else if (d1 == NULL)
			{
			continue;
			}
		d1->Print(std::cout);
		std::cout << std::endl;

		if (!GetDecision(input, &theVarList, &d2))
			{
			jdelete d1;
			break;
			}
		else if (d2 == NULL)
			{
			jdelete d1;
			continue;
			}
		d2->Print(std::cout);
		std::cout << std::endl;

		if (*d1 == *d2)
			{
			(JGetUserNotification())->DisplayMessage("These decisions are the same");
			}
		else
			{
			(JGetUserNotification())->DisplayMessage("These decisions are not the same");
			}

		jdelete d1;
		jdelete d2;
		}
}
logical Error :: GetDecision ( )
{

  *text = 0;
  return( GetDecision(error_srce) );

}
//================================================================================
//================================================================================
float CHuntEnemySchedule::GetDesire() const
{
    if ( !GetMemory() || !GetLocomotion() )
        return BOT_DESIRE_NONE;

    if ( !GetDecision()->CanHuntThreat() )
        return BOT_DESIRE_NONE;

    CEntityMemory *memory = GetBot()->GetPrimaryThreat();

    if ( memory == NULL )
        return BOT_DESIRE_NONE;

    // We have no vision of the enemy
    if ( HasCondition( BCOND_ENEMY_LOST ) ) {
        // But we have a vision of his last position and we are close
        if ( HasCondition( BCOND_ENEMY_LAST_POSITION_VISIBLE ) && (HasCondition( BCOND_ENEMY_TOO_NEAR ) || HasCondition( BCOND_ENEMY_NEAR )) )
            return BOT_DESIRE_NONE;
        
        return 0.65f;
    }

    // We do not have direct vision to the enemy (a person, window, etc.)
    if ( HasCondition( BCOND_ENEMY_OCCLUDED ) )
        return 0.65f;

    // We do not have range of attack
    if ( HasCondition( BCOND_TOO_FAR_TO_ATTACK ) )
        return 0.38f;

    return BOT_DESIRE_NONE;
}
logical Error :: GetDecision (void *error_source, const int16 err_code, char *errvar1, char *errvar2, char *errvar3, char *errvar4, char *errvar5, char *errvar6 )
{
  int16               errcd = err_code;
  if ( errvar1 )
    SetErrorVariable(1,errvar1);
  if ( errvar2 )
    SetErrorVariable(2,errvar2);
  if ( errvar3 )
    SetErrorVariable(3,errvar3);
  if ( errvar4 )
    SetErrorVariable(4,errvar4);
  if ( errvar5 )
    SetErrorVariable(5,errvar5);
  if ( errvar6 )
    SetErrorVariable(6,errvar6);

  if ( !errcd )
    errcd = USHORTMAX;
  SetError(errcd,NULL,NULL);
    
  return( GetDecision(error_source) );

}
logical Error :: GetDecision (const int16 err_code, char *errvar1, char *errvar2, char *errvar3, char *errvar4, char *errvar5, char *errvar6 )
{

  return(GetDecision(error_srce,err_code,errvar1,errvar2,errvar3,errvar4,errvar5,errvar6));

}
NAMESPACE_XGILL_BEGIN

/////////////////////////////////////////////////////////////////////
// CheckerDecisionPath
/////////////////////////////////////////////////////////////////////

bool CheckerDecisionTree::NextPath()
{
  m_path_position = 0;
  m_path_decision = m_root_id;

  if (m_unexplored_count == 0) {
    m_path.Clear();
    return false;
  }

  // the checker decision paths are binary strings of yes/no,
  // where the first entries in the path are the first decisions made.
  // treat the path as a binary number with 'yes' as 0, 'no' as 1,
  // and with the first entries in the path the least significant bits.
  // then we can get a breadth first search by repeatedly 'incrementing'
  // the path, which will explore the 'no' answers for the earliest
  // decisions the most frequently in relation to 'no' answers for
  // later decisions.

  // we will keep incrementing until we hit an unexplored part of the tree.
  // there is no sense exploring a path we know will give back incomplete.
  while (true) {

    size_t ind = 0;
    while (ind < m_path.Size() && !m_path[ind]) {
      m_path[ind] = true;
      ind++;
    }

    if (ind == m_path.Size())
      m_path.PushBack(false);
    else
      m_path[ind] = false;

    // check to see if this path is known to go to incomplete.
    bool is_incomplete = false;

    CheckerDecision *cur = GetDecision(m_root_id);
    for (size_t pos = 0; pos < m_path.Size(); pos++) {
      DecisionId next_id = m_path[pos] ? cur->m_child_yes : cur->m_child_no;
      if (next_id == 0) {
        Assert(cur->m_kind == CDK_Incomplete);
        is_incomplete = true;
        break;
      }

      cur = GetDecision(next_id);
    }

    if (!is_incomplete) {
      Assert(cur->m_kind == CDK_Unexplored);
      break;
    }
  }

  return true;
}