1
Fork 0
This repository has been archived on 2025-04-09. You can view files and clone it, but cannot push or open issues or pull requests.
puzzle-wuzzle-generator/include/dynamic_grid.hpp
2014-02-17 16:29:20 +01:00

89 lines
2.1 KiB
C++

#pragma once
#include "utilities.hpp"
#include <cassert>
#include <utility>
#include <vector>
#include <algorithm>
#include <random>
#include <iosfwd>
// Position {0,0} is bottom left.
// Position {W-1, H-1} is top right.
// template <typename T>
struct DynamicGrid{
using Position = std::pair<int, int>;
DynamicGrid(int width, int height, std::vector<int> && data);
//! \brief Returns an array of all valid positions (may be empty)
auto const & all_positions() const{
return positions;
}
//! \brief Returns true if p represents a valid position
auto valid(Position const & p) const {
return p.first >= 0 && p.second >= 0
&& p.first < W && p.second < H;
}
//! \brief Get (mutable) value at p
auto & get(Position const & p){
assert(valid(p));
return grid[static_cast<size_t>(p.first + p.second*W)];
}
//! \brief Get value at p
auto const& get(Position const & p) const {
assert(valid(p));
return grid[static_cast<size_t>(p.first + p.second*W)];
}
//! \brief Returns true if p represents an empty cell
auto empty(Position const & p) const {
assert(valid(p));
return get(p) == 0;
}
//! \brief Return true if the whole grid is empty
auto empty() const {
for(auto&& p : all_positions()){
if(!empty(p)) return false;
}
return true;
}
//! \brief Returns all neighbors of p
//! Only returns valid neighbors (and p does not need to be valid)
small_vector<Position, 4> neighbors(Position const & p) const;
//! \brief Let the block fall (all the way)
void collapse();
//! \brief Pretty prints grid to out
void print(std::ostream& out) const;
private:
int W;
int H;
std::vector<int> grid;
std::vector<Position> positions;
//! \brief Single vertical collapsing step
auto vcollapse();
//! \brief Single horizontal collapsing step
auto hcollapse();
//! \brief Returns true if the whole column at x is empty
auto empty_column(int x);
};
template <typename URNG>
auto random_dynamic_grid(int W, int H, int C, URNG&& r){
std::uniform_int_distribution<int> dis(1, C);
std::vector<int> v(W*H);
std::generate_n(std::begin(v), W*H, [&]{ return dis(r); });
return DynamicGrid(W, H, std::move(v));
}