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
|
||||
|
||||
#include "field.hpp"
|
||||
#include "utilities.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iosfwd>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
// Position {0,0} is bottom left.
|
||||
// Position {W-1, H-1} is top right.
|
||||
template <typename T>
|
||||
struct DynamicField{
|
||||
// template <typename T>
|
||||
struct DynamicGrid{
|
||||
using Position = std::pair<int, int>;
|
||||
|
||||
template <typename Input>
|
||||
DynamicField(int W, int H, Input it)
|
||||
DynamicGrid(int W, int H, Input it)
|
||||
: W(W)
|
||||
, H(H)
|
||||
, grid(W*H, 0)
|
||||
|
@ -56,26 +56,14 @@ struct DynamicField{
|
|||
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
|
||||
T& get(Position const & p){
|
||||
int & get(Position const & p){
|
||||
assert(valid(p));
|
||||
return grid[static_cast<size_t>(p.first + p.second*W)];
|
||||
}
|
||||
|
||||
//! \brief Get value at p
|
||||
T const& get(Position const & p) const {
|
||||
int const& get(Position const & p) const {
|
||||
assert(valid(p));
|
||||
return grid[static_cast<size_t>(p.first + p.second*W)];
|
||||
}
|
||||
|
@ -92,7 +80,17 @@ struct DynamicField{
|
|||
private:
|
||||
int W;
|
||||
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()
|
||||
static auto all_positions_impl(int W, int H) {
|
||||
|
@ -103,6 +101,14 @@ private:
|
|||
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
|
||||
auto vcollapse(){
|
||||
using namespace std;
|
||||
|
@ -143,14 +149,11 @@ private:
|
|||
return some_change;
|
||||
}
|
||||
|
||||
//! \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;
|
||||
public:
|
||||
//! \brief Let the block fall (all the way)
|
||||
auto collapse(){
|
||||
while(vcollapse());
|
||||
while(hcollapse());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -159,5 +162,5 @@ auto random_dynamic_grid(int W, int H, URNG&& r){
|
|||
std::uniform_int_distribution<int> dis(1, 2);
|
||||
std::vector<int> v(W*H);
|
||||
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
|
||||
|
||||
#include "field.hpp"
|
||||
#include "grid.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
|
|
|
@ -1,34 +1,20 @@
|
|||
#pragma once
|
||||
|
||||
#include "utilities.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#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 {W-1, H-1} is top right.
|
||||
template <int W, int H, typename T>
|
||||
struct Field{
|
||||
struct Grid{
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -162,5 +148,5 @@ private:
|
|||
//! \brief Helper function to create a field (T will be deducted)
|
||||
template <int W, int H, typename T>
|
||||
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