From f878a03c781fd57fea8447caaecee847ab576d8b Mon Sep 17 00:00:00 2001 From: dshaligram Date: Mon, 5 Feb 2007 19:17:37 +0000 Subject: Add support for block shuffling in maps (proposed by David). For instance: SHUFFLE: wW, 8$ will, if it swaps w and 8, also swap W and $. Block shuffles may have any number of comma-separated entries, provided each segment is the same length. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@923 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/mapdef.cc | 44 +++++++++++++++++++++++++++++++++++++++++--- crawl-ref/source/mapdef.h | 1 + 2 files changed, 42 insertions(+), 3 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc index b94ba68b4b..8c8d7624a3 100644 --- a/crawl-ref/source/mapdef.cc +++ b/crawl-ref/source/mapdef.cc @@ -242,19 +242,54 @@ void map_lines::calc_symbol_frequencies(symbol_frequency_t &f) std::string map_lines::remove_unreferenced(const symbol_frequency_t &freq, std::string s) { - for (int i = static_cast(s.length()) - 1; i >= 0; --i) + if (s.find(',') == std::string::npos) { - if (!freq[ s[i] ]) - s.erase( i, 1 ); + for (int i = static_cast(s.length()) - 1; i >= 0; --i) + { + if (!freq[ s[i] ]) + s.erase( i, 1 ); + } + } + else + { + s = replace_all_of(s, " \t", ""); } return (s); } +std::string map_lines::block_shuffle(const std::string &s) +{ + std::vector segs = split_string(",", s); + unsigned seglen = 0; + + std::vector shuffled; + for (int i = 0, size = segs.size(); i < size; ++i) + { + const int sel = random2(segs.size()); + + shuffled.push_back( segs[ sel ] ); + segs.erase( segs.begin() + sel ); + + if (!seglen) + seglen = shuffled[i].length(); + else if (seglen != shuffled[i].length()) + { + mprf(MSGCH_DIAGNOSTICS, "Bad shuffle parameter: %s", s.c_str()); + return (""); + } + } + + return comma_separated_line(shuffled.begin(), shuffled.end(), ",", ","); +} + std::string map_lines::shuffle(std::string s) { std::string result; + if (s.find(',') != std::string::npos) + return block_shuffle(s); + // Inefficient brute-force shuffle. while (!s.empty()) { @@ -272,6 +307,9 @@ void map_lines::resolve_shuffle(const symbol_frequency_t &freq, std::string toshuffle = remove_unreferenced(freq, shufflage); std::string shuffled = shuffle(toshuffle); + if (toshuffle.empty() || shuffled.empty()) + return; + for (int i = 0, size = lines.size(); i < size; ++i) { std::string &s = lines[i]; diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h index 25f3b7ef5a..3b104336a0 100644 --- a/crawl-ref/source/mapdef.h +++ b/crawl-ref/source/mapdef.h @@ -82,6 +82,7 @@ private: std::string remove_unreferenced(const symbol_frequency_t &freq, std::string s); std::string shuffle(std::string s); + std::string block_shuffle(const std::string &s); private: std::vector lines; -- cgit v1.2.3-54-g00ecf