Go to the documentation of this file.00001 #include <rl_env/gridworld.hh>
00002 #include <cmath>
00003
00004 std::ostream &operator<<(std::ostream &out, const Gridworld &g) {
00005 for (unsigned i = 0; i < g.ns.size(); ++i)
00006 out << " -";
00007 out << " \n";
00008
00009 for (unsigned h = g.ew.size() - 1; h > 0; --h) {
00010 out << "| ";
00011 for (unsigned w = 0; w < g.ew[h].size(); ++w)
00012 out << (g.ew[h][w] ? "| " : " ");
00013 out << "|\n";
00014
00015 for (unsigned w = 0; w < g.ns.size(); ++w)
00016 out << (g.ns[w][h-1] ? " -" : " ");
00017 out << " \n";
00018 }
00019
00020 out << "| ";
00021 for (unsigned w = 0; w < g.ew[0].size(); ++w)
00022 out << (g.ew[0][w] ? "| " : " ");
00023 out << "|\n";
00024
00025 for (unsigned i = 0; i < g.ns.size(); ++i)
00026 out << " -";
00027 out << " \n";
00028
00029 return out;
00030 }
00031
00032 Gridworld::Gridworld(unsigned height, unsigned width,
00033 const std::vector<std::vector<bool> > &northsouth,
00034 const std::vector<std::vector<bool> > &eastwest):
00035 h(height), w(width), ns(northsouth), ew(eastwest)
00036 {}
00037
00038 Gridworld::Gridworld(unsigned height, unsigned width, Random &rng):
00039 h(height), w(width),
00040 ns(w, std::vector<bool>(h - 1, false)),
00041 ew(h, std::vector<bool>(w - 1, false))
00042 {
00043 const unsigned n = static_cast<unsigned>(sqrt(static_cast<float>(w*h)));
00044 for (unsigned i = 0; i < n; ++i)
00045 add_obstacle(rng);
00046 }
00047
00048 bool Gridworld::wall(unsigned nsCoord, unsigned ewCoord, unsigned dir) const {
00049 const bool isNS = 0 == dir/2;
00050 const bool isIncr = 0 == dir%2;
00051 const std::vector<std::vector<bool> > &walls = isNS ? ns : ew;
00052 unsigned major = isNS ? ewCoord : nsCoord;
00053 unsigned minor = isNS ? nsCoord : ewCoord;
00054 if (!isIncr) {
00055 if (minor == 0)
00056 return true;
00057 --minor;
00058 }
00059 if (minor >= walls[major].size())
00060 return true;
00061 return walls[major][minor];
00062 }
00063
00064 void Gridworld::add_obstacle(Random &rng) {
00065 bool direction = rng.bernoulli(0.5);
00066 std::vector<std::vector<bool> > ¶llel = direction ? ns : ew;
00067 std::vector<std::vector<bool> > &perpendicular = direction ? ew : ns;
00068
00069 unsigned seedi = rng.uniformDiscrete(1, parallel.size()) - 1;
00070 unsigned seedj = rng.uniformDiscrete(1, parallel[seedi].size()) - 1;
00071
00072 unsigned first = seedi + 1;
00073 while (isClear(first - 1, seedj, parallel, perpendicular))
00074 --first;
00075 unsigned last = seedi;
00076 while (isClear(last + 1, seedj, parallel, perpendicular))
00077 ++last;
00078
00079 chooseSegment(first, last, seedj, parallel, rng);
00080 }
00081
00082 void Gridworld::chooseSegment(unsigned first,
00083 unsigned last,
00084 unsigned j,
00085 std::vector<std::vector<bool> > ¶llel,
00086 Random &rng)
00087 {
00088 if (last <= first)
00089 return;
00090 unsigned maxLength = last - first;
00091 if (maxLength >= parallel.size())
00092 maxLength = parallel.size() - 1;
00093 unsigned length = maxLength > 1 ? rng.uniformDiscrete(1,maxLength) : 1;
00094 int dir = 1 - 2*rng.uniformDiscrete(0,1);
00095 unsigned start = (dir > 0) ? first : (last - 1);
00096
00097 for (unsigned i = 0; i < length; ++i)
00098 parallel[start + i*dir][j] = true;
00099 }