📄 ase_threatboard.cpp
字号:
{
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 + -