⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ase_threatboard.cpp

📁 A*算法的演示程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      {
        unsigned int idx;
        idx = GetIndexForRowColumn(coveredposition->x, coveredposition->y);
        positionsUnderFire.push_back(idx);
      }

    ASE_Threat* threat;
    unsigned int idx;
    idx    = GetIndexForRowColumn(aRow, aCol);
    threat = GetThreatForLocation(idx);
    threat->SetPositionsUnderFire(positionsUnderFire);
    assert( threat->GetPositionsUnderFire()->size() == positionsUnderFire.size() );
  }


void ASE_ThreatBoard::ConstructPossibleThreatPositions(unsigned int   aRow, 
                                                       unsigned int   aCol, 
                                                       unsigned int   aMaximumMovement,
                                                       CoordPairList& thePositions
                                                     ) const
  {
    //! recursive implementation
    if ( aMaximumMovement == 0 )
      {
        ASE_CoordPair pair(aRow, aCol);
        thePositions.push_back(pair);
      }
    else
      {
        // move one step from aRow, aCol
        for ( int nx = -1; nx < 2; ++nx )
          {
            for ( int ny = -1; ny < 2; ++ny )
              {
                int r, c;
                r = nx + aRow;
                c = ny + aCol;
                if ( !m_kTerrainBoard->IsAccessibleBoardLocation(r, c) )
                  continue;

                ASE_CoordPair pair(r, c);
                if ( thePositions.end() != find(thePositions.begin(), thePositions.end(), pair) )
                  continue;
                // add pair and move from there as well
                ConstructPossibleThreatPositions(r, c, aMaximumMovement - 1, thePositions);
              }
          }
      }
  }


void ASE_ThreatBoard::ComputeLinesOfFireFromCell
                       (unsigned int   aRow, 
                        unsigned int   aCol,
                        CoordPairList& theCoveredPositions /*! in+out */
                       ) const
  {
    // obtain rays from template
    // for each ray
    // - test until
    //   - invalid location
    //   - blocked

    assert( !m_kTerrainBoard->IsLocationImpassable(aRow, aCol) );
    ASE_CoordPair here(aRow, aCol);
    theCoveredPositions.push_back(here);

    unsigned int nr_of_rays;
    nr_of_rays = m_PieTemplate.GetNumberOfRays();

    CoordPairList raytrace;

    for ( unsigned int ray = 0; ray < nr_of_rays; ++ray )
      {
        raytrace.clear();
        m_PieTemplate.GetRayForLocation(ray, here, raytrace);

        CoordPairList::const_iterator pos;
        for ( pos =  raytrace.begin(); 
              pos != raytrace.end(); 
              ++pos
            )
          {
            if ( !IsValidBoardLocation(pos->x, pos->y) )
              break;

            if ( m_kTerrainBoard->IsLocationImpassable(pos->x, pos->y) )
              break;

            // location pos can be seen, so add it to the list of coveredpositions
            // unless it is already part of it
            if (   theCoveredPositions.end() 
                == find(theCoveredPositions.begin(), theCoveredPositions.end(), *pos)
               )
              {
                theCoveredPositions.push_back(*pos);
              } 
          }
      }
  }


ASE_Board::CellValue ASE_ThreatBoard::DetermineLineOfFireRiskAnyLOF(unsigned int anIndex) const
  {
    // set 1 if under fire from any threat, 0 otherwise
    CellValue result;
    result = 0;

    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( (*threat)->IsAbleToFireAtLocation(anIndex) )
          {
            result = 1;
            break;
          }
      }

    return result;
  }


ASE_Board::CellValue ASE_ThreatBoard::DetermineLineOfFireRiskMinDistance(unsigned int anIndex) const
  {
    // set minimum distance to threat as value
    unsigned int x;
    unsigned int y;
    GetRowAndColumnForIndex(anIndex, x, y);

    int minDistance;
    minDistance = ( m_LineOfFireReach + m_ThreatMovement ) * ( m_LineOfFireReach + m_ThreatMovement );

    // iterate over all threats, and figure out which one is the closest able to see x(,y) 
    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( (*threat)->IsAbleToFireAtLocation(anIndex) )
          {
            unsigned int x2, y2;
            GetRowAndColumnForIndex((*threat)->GetLocation(), x2, y2);

            int dx, dy;
            dx = x - x2;
            dy = y - y2;

            int dist;
            dist = dx * dx + dy * dy;
            minDistance= min(dist, minDistance);
          }
      }
    
    float value;
    value  = sqrt(static_cast<float>(minDistance));
    value /= m_LineOfFireReach;
    value  = 1 - value;
    value *= (GetNumberOfValues() - 2);
    value += 1;
    
    CellValue result;
    result = static_cast<CellValue>(value);
    assert( result < (GetNumberOfValues() - 1) );

    return result;
  }


ASE_ThreatBoard::CellValue ASE_ThreatBoard::DetermineLineOfFireRiskLOFCount(unsigned int anIndex) const
  {
    // set lof count from threat as value
    unsigned int x;
    unsigned int y;
    GetRowAndColumnForIndex(anIndex, x, y);

    CellValue lofcount;
    lofcount = 0;

    // iterate over all threats, and count the number of threats able to see position
    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( (*threat)->IsAbleToFireAtLocation(anIndex) )
          {
            lofcount++;
          }
      }
 
    lofcount = min(lofcount, m_kMaxLOFCount);

    float value;
    value  = static_cast<float>(lofcount);
    value /= m_kMaxLOFCount;
    value *= (GetNumberOfValues() - 2);

    CellValue result;
    result = static_cast<CellValue>(value);

    return result;
  }


ASE_Board::CellValue ASE_ThreatBoard::DetermineLineOfFireRiskDistanceLOFCount(unsigned int anIndex) const
  {
    // set a weighted combination of threat count and distance to threat as value
    unsigned int x;
    unsigned int y;
    GetRowAndColumnForIndex(anIndex, x, y);

    const float kMaxDistance = 1.0f + static_cast<float>( m_LineOfFireReach + m_ThreatMovement );
    const float kMaxValue    = 4.0f /* threats */ * (kMaxDistance / 3.0f);

    float threatlofs;
    threatlofs = 0;

    // iterate over all threats, and figure out which one is the closest able to see x(,y) 
    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( (*threat)->IsAbleToFireAtLocation(anIndex) )
          {
            unsigned int x2, y2;
            GetRowAndColumnForIndex((*threat)->GetLocation(), x2, y2);

            int dx, dy;
            dx = x - x2;
            dy = y - y2;

            int dist;
            dist = dx * dx + dy * dy;

            float fdist;
            fdist = sqrt(static_cast<float>(dist));
 
            assert( kMaxDistance > fdist );
            threatlofs += (kMaxDistance - fdist);
          }
      }

    
    float value;
    value  = min(1.0f, threatlofs / kMaxValue );
    value *= (GetNumberOfValues() - 3);
    value += 1;
    
    CellValue result;
    result = static_cast<CellValue>(value);
    assert( result < (GetNumberOfValues() - 1) );

    return result;
  }


float ASE_ThreatBoard::GetRiskValue(int aRow, int aCol) const
  {
    unsigned int idx;
    idx = GetIndexForRowColumn(aRow, aCol);
    return GetRiskValue(idx);
  }


float ASE_ThreatBoard::GetRiskValue(unsigned int anIndex) const
  {
    if ( m_RiskModus == eAnyLineOfFire )
      {
        return IsEmptyCell(anIndex) ? 0.0f : 1.0f;
      }
    else
      {
        CellValue value;
        value = GetCellValue(anIndex);
        if ( value == 0 )
          return 0;

        float result;
        result  = static_cast<float>(value) / GetMaxRiskValue();
        result *= (1.0f - m_kBaseRisk);
        result += m_kBaseRisk;
        return result;
      }
  }


float ASE_ThreatBoard::GetMaxRiskValue() const
  {
    if ( m_RiskModus == eAnyLineOfFire )
      return 1.0f;
    else
      {
        assert(   ( m_RiskModus == eMinLineOfFireDistance )
               || ( m_RiskModus == eMinLineOfFireCount )
               || ( m_RiskModus == eMinLineOfFireCountAndDistance )
              );
        return static_cast<float>(m_kThreatPosition);
      }
  }


void ASE_ThreatBoard::GetThreatPositions(CoordPairList& thePositions /*! out */) const
  {
    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        int idx;
        idx = (*threat)->GetLocation();
 
        unsigned int row;
        unsigned int col;
        GetRowAndColumnForIndex(idx, row, col);
        thePositions.push_back(ASE_CoordPair(row, col));
      }
  }


const ASE_PieScan* ASE_ThreatBoard::GetLineOfSightTemplate() const
  {
    return &m_PieTemplate;
  }


void ASE_ThreatBoard::AddThreat(ASE_Threat* theThreat)
  {
    unsigned int idx;
    idx = theThreat->GetLocation();

    assert( !DoesSomeThreatOccupyLocation(idx) );
    m_Threats.push_back(theThreat);
  }


void ASE_ThreatBoard::RemoveThreat(unsigned int aLocation)
  {
    assert( DoesSomeThreatOccupyLocation(aLocation) );

    ThreatList::iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( aLocation == (*threat)->GetLocation() )
          {
            delete (*threat);
            m_Threats.erase(threat);
            return;
          }
      }
    assert( !"failed to find threat for aLocation" );
  }


bool ASE_ThreatBoard::DoesSomeThreatOccupyLocation(unsigned int aLocation) const
  {
    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( aLocation == (*threat)->GetLocation() )
          return true;
      }
    return false;
  }


ASE_Threat* ASE_ThreatBoard::GetThreatForLocation(unsigned int aLocation) const
  {
    assert( DoesSomeThreatOccupyLocation(aLocation) );

    ThreatList::const_iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        if ( aLocation == (*threat)->GetLocation() )
          return (*threat);
      }
    return 0;
  }


void ASE_ThreatBoard::RemoveAllThreats()
  {
    ThreatList::iterator threat;
    for ( threat =  m_Threats.begin();
          threat != m_Threats.end();
          ++threat
        )
      {
        delete (*threat);
      }
    m_Threats.clear();
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -