git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2927 c06c8d41-db1a-0410-9941-cceddc491573
REVECUB3H65Q6RELFWCJJJXN7EK4FB5JJYZP5VJHDDRCV7GXSQUQC
typedef std::pair<const monsters*,int> counted_monster;
typedef std::vector<counted_monster> counted_monster_list;
static void record_monster_by_name(counted_monster_list &list,
const monsters *mons)
{
const std::string name = mons->name(DESC_PLAIN);
for (counted_monster_list::iterator i = list.begin(); i != list.end(); ++i)
{
if (i->first->name(DESC_PLAIN) == name)
{
i->second++;
return;
}
}
list.push_back( counted_monster(mons, 1) );
}
static int monster_count(const counted_monster_list &list)
{
int nmons = 0;
for (counted_monster_list::const_iterator i = list.begin();
i != list.end(); ++i)
{
nmons += i->second;
}
return (nmons);
}
static std::string describe_monsters(const counted_monster_list &list)
{
std::ostringstream out;
description_level_type desc = DESC_CAP_THE;
for (counted_monster_list::const_iterator i = list.begin();
i != list.end(); desc = DESC_NOCAP_THE)
{
const counted_monster &cm(*i);
if (i != list.begin())
{
++i;
out << (i == list.end()? " and " : ", ");
}
else
++i;
// A collection of named things that can be stacked. The collection merges
// things that should be merged (by name) and outputs a comma-separated list
// with the preferred description type.
class named_thing_collection
{
public:
named_thing_collection();
void add_thing(const std::string &name);
std::string describe(description_level_type desc,
const char **plural_qualifiers = NULL,
const char **no_qualifier_suffix = NULL) const;
size_t size() const;
bool empty() const;
private:
typedef std::map<std::string, int> name_count_map;
name_count_map names;
size_t nnames;
};
//////////////////////////////////////////////////////////////////////////
// named_thing_collection
named_thing_collection::named_thing_collection()
: names(), nnames(0u)
{
}
void named_thing_collection::add_thing(const std::string &name)
{
names[name]++;
nnames++;
}
size_t named_thing_collection::size() const
{
return (nnames);
}
bool named_thing_collection::empty() const
{
return (!nnames);
}
std::string named_thing_collection::describe(
description_level_type desc,
const char **plural_qualifiers,
const char **no_qualifier_suffixes) const
{
if (empty())
return ("");
std::ostringstream out;
for (name_count_map::const_iterator i = names.begin();
i != names.end(); )
{
const std::pair<std::string, int> &curr(*i);
if (i != names.begin())
{
++i;
out << (i == names.end()? " and " : ", ");
}
else
++i;
const std::string name =
curr.second > 1? pluralise(curr.first, plural_qualifiers,
no_qualifier_suffixes)
: curr.first;
out << apply_description(desc, name, curr.second);
switch (desc)
{
case DESC_CAP_A:
desc = DESC_NOCAP_A;
break;
case DESC_CAP_THE:
desc = DESC_NOCAP_THE;
break;
case DESC_CAP_YOUR: case DESC_NOCAP_YOUR:
desc = DESC_PLAIN;
break;
default:
break;
}
}
return (out.str());
}
/////////////////////////////////////////////////////////////////////////