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-03-04 14:38:13 +01:00

90 lines
2.2 KiB
C++

#pragma once
#include "utilities.hpp"
#include "data.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 : public DynamicGridBase {
using Position = DynamicGridBase::Position;
DynamicGrid(int width, int height, std::vector<int> && data);
DynamicGrid() = default;
//! \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;
//! \brief Return a hash of the grid (hopefully unique)
size_t hash() const;
private:
//! \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));
}