1
Fork 0

Refactored Field -> Grid. Adds dynamic grid (without template)

This commit is contained in:
Joshua Moerman 2014-02-13 22:43:10 +01:00
parent 2f73ee4dc5
commit 58b4a320df
4 changed files with 57 additions and 49 deletions

View file

@ -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));
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "field.hpp" #include "grid.hpp"
#include <random> #include <random>

View file

@ -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
View 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]; }
};