Refactored Field -> Grid. Adds dynamic grid (without template)
This commit is contained in:
parent
2f73ee4dc5
commit
58b4a320df
4 changed files with 57 additions and 49 deletions
|
@ -1,23 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "field.hpp"
|
#include "utilities.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iosfwd>
|
#include <iostream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
// Position {0,0} is bottom left.
|
// Position {0,0} is bottom left.
|
||||||
// Position {W-1, H-1} is top right.
|
// Position {W-1, H-1} is top right.
|
||||||
template <typename T>
|
// template <typename T>
|
||||||
struct DynamicField{
|
struct DynamicGrid{
|
||||||
using Position = std::pair<int, int>;
|
using Position = std::pair<int, int>;
|
||||||
|
|
||||||
template <typename Input>
|
template <typename Input>
|
||||||
DynamicField(int W, int H, Input it)
|
DynamicGrid(int W, int H, Input it)
|
||||||
: W(W)
|
: W(W)
|
||||||
, H(H)
|
, H(H)
|
||||||
, grid(W*H, 0)
|
, grid(W*H, 0)
|
||||||
|
@ -56,26 +56,14 @@ struct DynamicField{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Let the block fall (all the way)
|
|
||||||
auto collapse(){
|
|
||||||
while(vcollapse());
|
|
||||||
while(hcollapse());
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \brief Returns an array of all valid positions
|
|
||||||
auto const & all_positions() const {
|
|
||||||
static auto v = all_positions_impl(W, H);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \brief Get (mutable) value at p
|
//! \brief Get (mutable) value at p
|
||||||
T& get(Position const & p){
|
int & get(Position const & p){
|
||||||
assert(valid(p));
|
assert(valid(p));
|
||||||
return grid[static_cast<size_t>(p.first + p.second*W)];
|
return grid[static_cast<size_t>(p.first + p.second*W)];
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Get value at p
|
//! \brief Get value at p
|
||||||
T const& get(Position const & p) const {
|
int const& get(Position const & p) const {
|
||||||
assert(valid(p));
|
assert(valid(p));
|
||||||
return grid[static_cast<size_t>(p.first + p.second*W)];
|
return grid[static_cast<size_t>(p.first + p.second*W)];
|
||||||
}
|
}
|
||||||
|
@ -92,7 +80,17 @@ struct DynamicField{
|
||||||
private:
|
private:
|
||||||
int W;
|
int W;
|
||||||
int H;
|
int H;
|
||||||
std::vector<T> grid;
|
std::vector<int> grid;
|
||||||
|
|
||||||
|
//! \brief Returns true if the whole column at x is empty
|
||||||
|
auto empty_column(int x){
|
||||||
|
for(auto y = 0; y < H; ++y){
|
||||||
|
if(!empty({x, y})){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//! \brief Helper function for all_positions()
|
//! \brief Helper function for all_positions()
|
||||||
static auto all_positions_impl(int W, int H) {
|
static auto all_positions_impl(int W, int H) {
|
||||||
|
@ -103,6 +101,14 @@ private:
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
//! \brief Returns an array of all valid positions
|
||||||
|
auto const & all_positions() const {
|
||||||
|
static auto v = all_positions_impl(W, H);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
//! \brief Single vertical collapsing step
|
//! \brief Single vertical collapsing step
|
||||||
auto vcollapse(){
|
auto vcollapse(){
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -143,14 +149,11 @@ private:
|
||||||
return some_change;
|
return some_change;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Returns true if the whole column at x is empty
|
public:
|
||||||
auto empty_column(int x){
|
//! \brief Let the block fall (all the way)
|
||||||
for(auto y = 0; y < H; ++y){
|
auto collapse(){
|
||||||
if(!empty({x, y})){
|
while(vcollapse());
|
||||||
return false;
|
while(hcollapse());
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -159,5 +162,5 @@ auto random_dynamic_grid(int W, int H, URNG&& r){
|
||||||
std::uniform_int_distribution<int> dis(1, 2);
|
std::uniform_int_distribution<int> dis(1, 2);
|
||||||
std::vector<int> v(W*H);
|
std::vector<int> v(W*H);
|
||||||
std::generate_n(std::begin(v), W*H, [&]{ return dis(r); });
|
std::generate_n(std::begin(v), W*H, [&]{ return dis(r); });
|
||||||
return DynamicField<int>(W, H, std::begin(v));
|
return DynamicGrid(W, H, std::begin(v));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "field.hpp"
|
#include "grid.hpp"
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "utilities.hpp"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
||||||
// Simple static vector (much faster)
|
|
||||||
// Also slightly faster than boost::container::static_vector
|
|
||||||
// No checking is performed!
|
|
||||||
template <typename T, size_t Max>
|
|
||||||
struct small_vector{
|
|
||||||
std::array<T, Max> arr;
|
|
||||||
size_t elements = 0;
|
|
||||||
|
|
||||||
void push_back(T const & t){
|
|
||||||
arr[elements++] = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto begin() const { return &arr[0]; }
|
|
||||||
auto end() const { return &arr[elements]; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Position {0,0} is bottom left.
|
// Position {0,0} is bottom left.
|
||||||
// Position {W-1, H-1} is top right.
|
// Position {W-1, H-1} is top right.
|
||||||
template <int W, int H, typename T>
|
template <int W, int H, typename T>
|
||||||
struct Field{
|
struct Grid{
|
||||||
using Position = std::pair<int, int>;
|
using Position = std::pair<int, int>;
|
||||||
|
|
||||||
Field(std::initializer_list<T> g){
|
Grid(std::initializer_list<T> g){
|
||||||
std::copy(std::begin(g), std::end(g), std::begin(grid));
|
std::copy(std::begin(g), std::end(g), std::begin(grid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,5 +148,5 @@ private:
|
||||||
//! \brief Helper function to create a field (T will be deducted)
|
//! \brief Helper function to create a field (T will be deducted)
|
||||||
template <int W, int H, typename T>
|
template <int W, int H, typename T>
|
||||||
auto create_rectangular_field(std::initializer_list<T> grid){
|
auto create_rectangular_field(std::initializer_list<T> grid){
|
||||||
return Field<W, H, T>(grid);
|
return Grid<W, H, T>(grid);
|
||||||
}
|
}
|
19
include/utilities.hpp
Normal file
19
include/utilities.hpp
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
// Simple static vector (much faster)
|
||||||
|
// Also slightly faster than boost::container::static_vector
|
||||||
|
// No checking is performed!
|
||||||
|
template <typename T, size_t Max>
|
||||||
|
struct small_vector{
|
||||||
|
std::array<T, Max> arr;
|
||||||
|
size_t elements = 0;
|
||||||
|
|
||||||
|
void push_back(T const & t){
|
||||||
|
arr[elements++] = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin() const { return &arr[0]; }
|
||||||
|
auto end() const { return &arr[elements]; }
|
||||||
|
};
|
Reference in a new issue