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

View file

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

View file

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