Before Cellrays: 3709 Fullrays: 399 Compressed: 441 After Cellrays: 3709 Fullrays: 399 Minimal cellrays: 266
Slight speed up in both precomputation and LOS computation:
before after
all los tests 14s 12s just los_maps test 1.7s 1.5s
W2JKSN3BG7JHORONWK6J53OOEJ3EBVKY5QTBG4ITNVORLWRZNU5QC
5KZF63OICCGFAZ5E3TRS5GKZJLKQYWLGKOA7IYV4X3C6AOXB4MMAC
ACZYEIX7WMPIIODKCATBCUE626AJ4ZGGBOMVC6BGXM27EQU2RECAC
WY3Q6JZ3HTBF2CYFJOUVG4MMFINBK4PI2DJ625CVKMJ5BPMXAW2AC
ICVDXXH2Z5MV7BLYVWQNLQSV63THIB4E6NVORIDBB7D6TBEHBXOAC
ZJBFGI5FGCP7WGFKEUTLWZK4ATGB35Q4I5IB4BKJTHVKS2HDR5LQC
PHJ2TT2CQ2IRXOB5KAV2664KKTPYFPFUIBEGAOQBGB4SAZ7PKNHAC
// Returns a vector which lists all the nonduped cellrays (by index).
// A cellray c in a fullray f is duped if there is a fullray g
// such that g contains c and g[:c] is a subset of f[:c].
static std::vector<int> _find_nonduped_cellrays()
// A cellray given by fullray and length.
struct cellray
bool is_duplicate;
std::vector<int> result;
los_ray ray;
int length;
cellray(const los_ray& r, int l)
: ray(r), length(l)
{
}
int index() const
{
return ray.start + length;
}
coord_def end() const
{
return ray_coords[index()];
}
};
enum compare_type
{
C_SUBRAY,
C_SUPERRAY,
C_NEITHER
};
compare_type _compare_cellrays(const cellray& a, const cellray& b)
{
if (a.end() != b.end())
return C_NEITHER;
if (_is_subset(a.ray.start, b.ray.start, a.length, b.length))
return C_SUBRAY;
if (_is_subset(b.ray.start, a.ray.start, b.length, a.length))
return C_SUPERRAY;
else
return C_NEITHER;
}
// Returns a vector which lists all minimal cellrays (by index).
static std::vector<int> _find_minimal_cellrays()
{
FixedArray<std::list<cellray>, LOS_MAX_RANGE+1, LOS_MAX_RANGE+1> minima;
std::list<cellray>::iterator min_it;
// Is the cellray ray[0..i] duplicated?
is_duplicate = false;
// XXX: We should really check everything up to now
// completely, and all further rays to see if they're
// proper subsets.
// Is the cellray ray[0..i] duplicated so far?
bool dup = false;
cellray c(ray, i);
std::list<cellray>& min = minima(c.end());
// Short-circuit if we've passed ray[i]
// in either coordinate.
if (prev[j].x > ray[i].x || prev[j].y > ray[i].y)
break;
if (prev[j] == ray[i])
{
is_duplicate = _is_subset(prev.start, ray.start,
j, i);
break;
}
case C_SUBRAY:
dup = true;
break;
case C_SUPERRAY:
min_it = min.erase(min_it);
// clear this should be added, but might have
// to erase more
break;
case C_NEITHER:
default:
break;
std::vector<int> nondupe_cellrays = _find_nonduped_cellrays();
const int n_nondupe_rays = nondupe_cellrays.size();
cellray_ends.resize(n_nondupe_rays);
for (int i = 0; i < n_nondupe_rays; ++i)
cellray_ends[i] = ray_coords[nondupe_cellrays[i]];
std::vector<int> min_cellrays = _find_minimal_cellrays();
const int n_min_rays = min_cellrays.size();
cellray_ends.resize(n_min_rays);
for (int i = 0; i < n_min_rays; ++i)
cellray_ends[i] = ray_coords[min_cellrays[i]];
mprf( MSGCH_DIAGNOSTICS, "Cellrays: %d Fullrays: %u Compressed: %u",
n_cellrays, fullrays.size(), n_nondupe_rays );
mprf( MSGCH_DIAGNOSTICS, "Cellrays: %d Fullrays: %u Minimal cellrays: %u",
n_cellrays, fullrays.size(), n_min_rays );